From 7350d4087490eb5606b731a65f629200622e86f0 Mon Sep 17 00:00:00 2001 From: Kenneth Lee Date: Wed, 26 Jun 2024 11:26:06 +0100 Subject: [PATCH 01/66] LUPEYALPHA-543 - First pass of FE landing-page * A few TBC values need to be added, but for another ticket * Journey closed content not present, so just hide the button * OneLogin continue application link is a placeholder until OL works is started * Enabled raise_on_missing_translations=true for development env --- .../landing_page.html.erb | 113 +++++++++++++++++- config/environments/development.rb | 2 +- config/locales/en.yml | 1 + 3 files changed, 111 insertions(+), 5 deletions(-) diff --git a/app/views/further_education_payments/landing_page.html.erb b/app/views/further_education_payments/landing_page.html.erb index 9f9b62041a..eac4c254f3 100644 --- a/app/views/further_education_payments/landing_page.html.erb +++ b/app/views/further_education_payments/landing_page.html.erb @@ -1,5 +1,110 @@ -

- further education landing page goes here -

+
+
+

<%= t("further_education_payments.landing_page") %>

-<%= govuk_start_button(text: "Start now", href: claim_path(current_journey_routing_name, "claim")) %> +

+ Use this service to check your eligibility for an incentive payment before you apply. +

+ +

+ Before starting your application, it may be useful to have the following information to hand: +

+ +
    +
  • your contract or written statement of employment
  • +
  • your teaching timetable
  • +
  • the name of your college or sixth-form group, if your further education (FE) provider is part of one
  • +
+ +

+ Answering questions about eligibility takes [TBC] minutes and applying for the payment takes another [TBC] minutes. +

+ +
+

+ You’ll need a GOV.UK One Login account to apply for a further education financial incentive payment. If you don’t have an account yet, we’ll help you create one. +

+ +

To create a GOV.UK One Login, you’ll need:

+ +
    +
  • an email address
  • +
  • a way to get security codes - this can be a mobile phone number or an authenticator app
  • +
+
+ + <%# TODO: There isn't any journey closed content, for now hide the button %> + <% if @journey_open %> + <%= govuk_start_button(text: "Start now", href: claim_path(current_journey_routing_name, "claim")) %> + <% end %> + +

Continue an existing application

+ +

+ If you have already started an application, you can <%= govuk_link_to "continue it [TBC]" %>. You will be asked to sign in to GOV.UK One Login if you are not signed in already. +

+ +

Eligibility criteria

+ +

+ Eligible early career FE teachers can claim an annual incentive payment to encourage them to continue teaching. +

+ +

+ Claimants should be in the first 5 years of their teaching career in England and teach specific courses in the following subject areas: +

+ +
    +
  • building and construction
  • +
  • chemistry
  • +
  • computing, including digital and ICT
  • +
  • early years
  • +
  • engineering and manufacturing, including transport engineering and electronics
  • +
  • maths
  • +
  • physics
  • +
+ +

+ Further information about the eligibility criteria can be found in the <%= govuk_link_to "levelling up premium payments for FE teachers guidance", "https://www.gov.uk/guidance/levelling-up-premium-payments-for-fe-teachers", target: "_blank" %>. +

+ +

Payments and deductions

+ +

+ If you meet the eligibility criteria, you could be eligible for between £2,000 and £6,000. The amount you are eligible for depends on: +

+ +
    +
  • <%= govuk_link_to "the FE provider you teach in [TBC]" %>
  • +
  • the number of hours you teach
  • +
+ +

+ The incentive payment is taxable income, so the amount you receive may be lower following tax deductions. If you are currently paying off a student loan, a deduction from your payment will also go towards repaying it. +

+ +

Further information

+ +

+ You must apply between [MONTH TBC] <%= @academic_year.start_year.to_s %> and March <%= @academic_year.end_year.to_s %>. +

+ +

+ If you are eligible for an incentive payment, we will collect personal information to verify your claim and process your payment. +

+ +

+ Payments are given up to [TBC] weeks from applying. You will receive an approval email with further information on your application. +

+ +

Contact

+ +

+ For further support, email +
+ <%= govuk_link_to "FE-Levellingup.PremiumPayments@education.gov.uk", "mailto:FE-Levellingup.PremiumPayments@education.gov.uk", no_visited_state: true %>. +

+ +

You should receive a reply within [TBC] working days.

+
+
diff --git a/config/environments/development.rb b/config/environments/development.rb index 757faa36a0..e98dbb2339 100644 --- a/config/environments/development.rb +++ b/config/environments/development.rb @@ -72,7 +72,7 @@ config.assets.quiet = true # Raises error for missing translations. - # config.i18n.raise_on_missing_translations = true + config.i18n.raise_on_missing_translations = true # Annotate rendered view with file names. # config.action_view.annotate_rendered_view_with_filenames = true diff --git a/config/locales/en.yml b/config/locales/en.yml index 74665b3ef0..9de1fc324d 100644 --- a/config/locales/en.yml +++ b/config/locales/en.yml @@ -764,6 +764,7 @@ en: confirmation_notice: "By selecting continue you are confirming that, to the best of your knowledge, the details you are providing are correct." further_education_payments: + landing_page: Find out if you are eligible for any incentive payments for further education teachers claim_description: for further education payments journey_name: Claim incentive payments for further education teachers feedback_email: "fe-levellingup.premiumpayments@education.gov.uk" From 5db2aa9a71378ff7cd020cfe68b86f6b17eb8f0a Mon Sep 17 00:00:00 2001 From: Richard Lynch Date: Fri, 21 Jun 2024 17:12:51 +0100 Subject: [PATCH 02/66] Remove trainee pages IRP is no longer going to be eligible for trainee teachers. This commit removes the trainee teacher screens we'd migrated so far and updates the eligibility to make trainee teachers ineligible. We've also removed the resetting of depenent answers from the application for as now if the user changes their answer to any of the options they'll be unable to proceed with the reset of the journey. --- .../application_route_form.rb | 10 -- .../subject_form.rb | 6 +- .../trainee_details_form.rb | 27 ---- .../get_a_teacher_relocation_payment.rb | 1 - .../answers_presenter.rb | 23 +-- .../session_answers.rb | 4 - .../slug_sequence.rb | 10 +- .../policy_eligibility_checker.rb | 2 + .../claims/subject.html.erb | 6 +- .../claims/trainee_details.html.erb | 34 ----- config/locales/en.yml | 25 +--- ...eligible_route_completing_the_form_spec.rb | 138 +++++++----------- .../trainee_route_completing_the_form_spec.rb | 57 -------- .../application_route_form_spec.rb | 60 -------- .../subject_form_spec.rb | 18 +-- .../trainee_details_form_spec.rb | 46 ------ .../answers_presenter_spec.rb | 125 ++++++---------- .../policy_eligibility_checker_spec.rb | 4 +- .../step_helpers.rb | 30 +--- 19 files changed, 120 insertions(+), 506 deletions(-) delete mode 100644 app/forms/journeys/get_a_teacher_relocation_payment/trainee_details_form.rb delete mode 100644 app/views/get_a_teacher_relocation_payment/claims/trainee_details.html.erb delete mode 100644 spec/features/get_a_teacher_relocation_payment/trainee_route_completing_the_form_spec.rb delete mode 100644 spec/forms/journeys/get_a_teacher_relocation_payment/trainee_details_form_spec.rb diff --git a/app/forms/journeys/get_a_teacher_relocation_payment/application_route_form.rb b/app/forms/journeys/get_a_teacher_relocation_payment/application_route_form.rb index 7e3caa055e..b01db5163a 100644 --- a/app/forms/journeys/get_a_teacher_relocation_payment/application_route_form.rb +++ b/app/forms/journeys/get_a_teacher_relocation_payment/application_route_form.rb @@ -15,16 +15,6 @@ def available_options def save return false unless valid? - if application_route_changed? - journey_session.answers.assign_attributes( - state_funded_secondary_school: nil, - one_year: nil, - start_date: nil, - subject: nil, - visa_type: nil - ) - end - journey_session.answers.assign_attributes( application_route: application_route ) diff --git a/app/forms/journeys/get_a_teacher_relocation_payment/subject_form.rb b/app/forms/journeys/get_a_teacher_relocation_payment/subject_form.rb index af352600f8..41339e06f9 100644 --- a/app/forms/journeys/get_a_teacher_relocation_payment/subject_form.rb +++ b/app/forms/journeys/get_a_teacher_relocation_payment/subject_form.rb @@ -9,11 +9,7 @@ class SubjectForm < Form } def available_options - if answers.trainee? - %w[physics languages other] - else - %w[physics combined_with_physics languages other] - end + %w[physics combined_with_physics languages other] end def save diff --git a/app/forms/journeys/get_a_teacher_relocation_payment/trainee_details_form.rb b/app/forms/journeys/get_a_teacher_relocation_payment/trainee_details_form.rb deleted file mode 100644 index 649c07806f..0000000000 --- a/app/forms/journeys/get_a_teacher_relocation_payment/trainee_details_form.rb +++ /dev/null @@ -1,27 +0,0 @@ -module Journeys - module GetATeacherRelocationPayment - class TraineeDetailsForm < Form - attribute :state_funded_secondary_school, :boolean - - validates :state_funded_secondary_school, - inclusion: { - in: [true, false], - message: i18n_error_message(:inclusion) - } - - def available_options - [true, false] - end - - def save - return false unless valid? - - journey_session.answers.assign_attributes( - state_funded_secondary_school: state_funded_secondary_school - ) - - journey_session.save! - 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 3b2a856e29..e81608b897 100644 --- a/app/models/journeys/get_a_teacher_relocation_payment.rb +++ b/app/models/journeys/get_a_teacher_relocation_payment.rb @@ -11,7 +11,6 @@ module GetATeacherRelocationPayment "claims" => { "application-route" => ApplicationRouteForm, "state-funded-secondary-school" => StateFundedSecondarySchoolForm, - "trainee-details" => TraineeDetailsForm, "contract-details" => ContractDetailsForm, "start-date" => StartDateForm, "subject" => SubjectForm, 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 6ad3aa21d6..c01009f512 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 @@ -6,18 +6,11 @@ class AnswersPresenter < BaseAnswersPresenter def eligibility_answers [].tap do |a| a << application_route - if answers.trainee? - a << trainee_details - else - a << state_funded_secondary_school - a << contract_details - end + a << state_funded_secondary_school + a << contract_details a << start_date_details a << subject_details - # FIXME RL we'll soon be removing trainee screens from the journey - # so we're just adding this for the time being to save having to - # write a test we'll be deleting in the next commit - a << visa_details unless answers.trainee? + a << visa_details end.compact end @@ -39,14 +32,6 @@ def state_funded_secondary_school ] end - def trainee_details - [ - t("get_a_teacher_relocation_payment.forms.trainee_details.question"), - t("get_a_teacher_relocation_payment.forms.trainee_details.answers.#{answers.state_funded_secondary_school}.answer"), - "trainee-details" - ] - end - def contract_details [ t("get_a_teacher_relocation_payment.forms.contract_details.question"), @@ -65,7 +50,7 @@ def start_date_details def subject_details [ - t("get_a_teacher_relocation_payment.forms.subject.question.#{answers.application_route}"), + t("get_a_teacher_relocation_payment.forms.subject.question"), t("get_a_teacher_relocation_payment.forms.subject.answers.#{answers.subject}"), "subject" ] 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 c1d29ad3f2..7c61ee2a61 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,10 +7,6 @@ class SessionAnswers < Journeys::SessionAnswers attribute :start_date, :date attribute :subject, :string attribute :visa_type, :string - - def trainee? - application_route == "salaried_trainee" - end 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 50b98ed539..c89b0728b0 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 @@ -4,7 +4,6 @@ class SlugSequence ELIGIBILITY_SLUGS = [ "application-route", "state-funded-secondary-school", - "trainee-details", "contract-details", "start-date", "subject", @@ -36,14 +35,7 @@ def initialize(journey_session) end def slugs - SLUGS.dup.tap do |sequence| - if answers.trainee? - sequence.delete("state-funded-secondary-school") - sequence.delete("contract-details") - else - sequence.delete("trainee-details") - end - end + SLUGS.dup end end end 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 f35e1cf2a6..e64f6009ba 100644 --- a/app/models/policies/international_relocation_payments/policy_eligibility_checker.rb +++ b/app/models/policies/international_relocation_payments/policy_eligibility_checker.rb @@ -23,6 +23,8 @@ def ineligible? def ineligible_reason case answers.attributes.symbolize_keys + in application_route: "salaried_trainee" + "application route salaried trainee not accecpted" in application_route: "other" "application route other not accecpted" in state_funded_secondary_school: false diff --git a/app/views/get_a_teacher_relocation_payment/claims/subject.html.erb b/app/views/get_a_teacher_relocation_payment/claims/subject.html.erb index e1f9d7e9a9..48be6db057 100644 --- a/app/views/get_a_teacher_relocation_payment/claims/subject.html.erb +++ b/app/views/get_a_teacher_relocation_payment/claims/subject.html.erb @@ -1,7 +1,7 @@ <% content_for( :page_title, page_title( - t("get_a_teacher_relocation_payment.forms.subject.question.#{@form.answers.application_route}"), + t("get_a_teacher_relocation_payment.forms.subject.question"), journey: current_journey_routing_name, show_error: @form.errors.any? ) @@ -22,8 +22,8 @@ f.object.available_options, -> (option) { option }, -> (option) { t("get_a_teacher_relocation_payment.forms.subject.answers.#{option}") }, - legend: { text: t("get_a_teacher_relocation_payment.forms.subject.question.#{f.object.answers.application_route}") }, - hint: { text: t("get_a_teacher_relocation_payment.forms.subject.hint.#{f.object.answers.application_route}") } + legend: { text: t("get_a_teacher_relocation_payment.forms.subject.question") }, + hint: { text: t("get_a_teacher_relocation_payment.forms.subject.hint") } ) %> <%= f.govuk_submit %> diff --git a/app/views/get_a_teacher_relocation_payment/claims/trainee_details.html.erb b/app/views/get_a_teacher_relocation_payment/claims/trainee_details.html.erb deleted file mode 100644 index c0115b68e1..0000000000 --- a/app/views/get_a_teacher_relocation_payment/claims/trainee_details.html.erb +++ /dev/null @@ -1,34 +0,0 @@ -<% content_for( - :page_title, - page_title( - t("get_a_teacher_relocation_payment.forms.trainee_details.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_collection_radio_buttons( - :state_funded_secondary_school, - f.object.available_options, - -> (option) { option }, - -> (option) { t("get_a_teacher_relocation_payment.forms.trainee_details.answers.#{option}.answer") }, - legend: { text: t("get_a_teacher_relocation_payment.forms.trainee_details.question") }, - hint: { text: t("get_a_teacher_relocation_payment.forms.trainee_details.hint_html") } - ) %> - - <%= f.govuk_submit %> - <% end %> -
-
- - diff --git a/config/locales/en.yml b/config/locales/en.yml index 9de1fc324d..2d60548386 100644 --- a/config/locales/en.yml +++ b/config/locales/en.yml @@ -707,23 +707,6 @@ en: answer: "No" errors: inclusion: "Select the option that applies to you" - trainee_details: - question: "Are you on a teacher training course in England which meets the following conditions?" - hint_html: > - The course must: - - Check with your training provider if you're not sure. - answers: - true: - answer: "Yes" - false: - answer: "No" - errors: - inclusion: "Select the option that applies to you" contract_details: question: "Are you employed on a contract lasting at least one year?" hint: "Your contract can also be ongoing or permanent." @@ -739,12 +722,8 @@ en: errors: presence: "Enter your contract start date" subject: - question: - teacher: "What subject are you employed to teach at your school?" - salaried_trainee: "What subject are you training to teach?" - hint: - teacher: "Physics, general or combined science including physics, and languages can be combined with other subjects but must make up at least 50% of your time in the classroom." - salaried_trainee: "Physics or languages can be combined with other subjects but must make up at least 50% of your course content." + question: "What subject are you employed to teach at your school?" + hint: "Physics, general or combined science including physics, and languages can be combined with other subjects but must make up at least 50% of your time in the classroom." answers: physics: "Physics" combined_with_physics: "General or combined science, including physics" 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 fb1fb0966d..9a4b2a1808 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 @@ -21,10 +21,22 @@ describe "navigating forward" do context "ineligible - application route" do - it "shows the ineligible page" do - when_i_start_the_form - and_i_complete_application_route_question_with(option: "Other") - then_i_see_the_ineligible_page + context "when choosing other" do + it "shows the ineligible page" do + when_i_start_the_form + and_i_complete_application_route_question_with(option: "Other") + then_i_see_the_ineligible_page + end + end + + context "when choosing trainee" do + it "shows the ineligible page" do + when_i_start_the_form + and_i_complete_application_route_question_with( + option: "I am enrolled on a salaried teacher training course in England" + ) + then_i_see_the_ineligible_page + end end end @@ -39,17 +51,6 @@ end end - context "ineligible - trainee details" do - it "shows the ineligible page" do - when_i_start_the_form - and_i_complete_application_route_question_with( - option: "I am enrolled on a salaried teacher training course in England" - ) - and_i_complete_the_trainee_details_step_with(option: "No") - then_i_see_the_ineligible_page - end - end - context "ineligible - contract details" do it "shows the ineligible page" do when_i_start_the_form @@ -65,85 +66,50 @@ # FIXME RL waiting on feedback from policy team to determine what the cut # off date is for contracts xcontext "ineligible - contract start date" do - context "as a teacher" 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: Polices::InternationalRelocationPayments.earliest_eligible_contract_start_date - 1.day - ) - then_i_see_the_ineligible_page - end - end - - context "as a trainee" do - it "shows the ineligible page" do - when_i_start_the_form - and_i_complete_application_route_question_with( - option: "I am enrolled on a salaried teacher training course in England" - ) - and_i_complete_the_trainee_details_step_with(option: "Yes") - and_i_complete_the_contract_start_date_step_with( - date: Polices::InternationalRelocationPayments.earliest_eligible_contract_start_date - 1.day - ) - then_i_see_the_ineligible_page - end + 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: Polices::InternationalRelocationPayments.earliest_eligible_contract_start_date - 1.day + ) + then_i_see_the_ineligible_page end end context "ineligible - subject" do - context "as a teacher" 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: "Other") - then_i_see_the_ineligible_page - end - end - - context "as a trainee" do - it "shows the ineligible page" do - when_i_start_the_form - and_i_complete_application_route_question_with( - option: "I am enrolled on a salaried teacher training course in England" - ) - and_i_complete_the_trainee_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: "Other", trainee: true) - then_i_see_the_ineligible_page - end + 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: "Other") + then_i_see_the_ineligible_page end end context "ineligible - visa" do - context "as a teacher" 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: "Other") - then_i_see_the_ineligible_page - end + 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: "Other") + then_i_see_the_ineligible_page end end end diff --git a/spec/features/get_a_teacher_relocation_payment/trainee_route_completing_the_form_spec.rb b/spec/features/get_a_teacher_relocation_payment/trainee_route_completing_the_form_spec.rb deleted file mode 100644 index 8769027d18..0000000000 --- a/spec/features/get_a_teacher_relocation_payment/trainee_route_completing_the_form_spec.rb +++ /dev/null @@ -1,57 +0,0 @@ -require "rails_helper" - -describe "trainee route: completing the form" do - include GetATeacherRelocationPayment::StepHelpers - - let(:journey_configuration) do - create(:journey_configuration, :get_a_teacher_relocation_payment) - end - - let(:contract_start_date) do - Date.tomorrow - end - - before do - journey_configuration - end - - describe "navigating forward" do - # Well be removing this feature spec in the next commit - xit "submits an application" do - when_i_start_the_form - and_i_complete_application_route_question_with( - option: "I am enrolled on a salaried teacher training course in England" - ) - and_i_complete_the_trainee_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", trainee: true) - 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 - and_i_submit_the_application - then_the_application_is_submitted_successfully - end - end - - def then_the_check_your_answers_part_one_page_shows_my_answers - assert_on_check_your_answers_part_one_page! - - expect(page).to have_text( - "What is your employment status? I am enrolled on a salaried teacher training course in England" - ) - - expect(page).to have_text( - "Are you on a teacher training course in England which meets the following conditions? Yes" - ) - - expect(page).to have_text( - "Enter the start date of your contract #{contract_start_date.strftime("%d-%m-%Y")}" - ) - - expect(page).to have_text( - "What subject are you training to teach? Physics" - ) - end -end diff --git a/spec/forms/journeys/get_a_teacher_relocation_payment/application_route_form_spec.rb b/spec/forms/journeys/get_a_teacher_relocation_payment/application_route_form_spec.rb index 1dbac0f032..b6fbabed07 100644 --- a/spec/forms/journeys/get_a_teacher_relocation_payment/application_route_form_spec.rb +++ b/spec/forms/journeys/get_a_teacher_relocation_payment/application_route_form_spec.rb @@ -37,65 +37,5 @@ change { journey_session.reload.answers.application_route }.to("teacher") ) end - - describe "reseting dependent answers" do - before do - journey_session.answers.assign_attributes( - application_route: existing_option, - state_funded_secondary_school: true, - one_year: true, - start_date: Date.new(2024, 1, 1), - subject: "physics", - visa_type: "British National (Overseas) visa_type" - ) - journey_session.save! - end - - context "when the value has changed" do - let(:existing_option) { "salaried_trainee" } - - it "resets dependent answers" do - expect { expect(form.save).to be(true) }.to( - change { journey_session.reload.answers.state_funded_secondary_school } - .from(true) - .to(nil) - .and( - change { journey_session.reload.answers.one_year } - .from(true) - .to(nil) - ) - .and( - change { journey_session.reload.answers.start_date } - .from(Date.new(2024, 1, 1)) - .to(nil) - ) - .and( - change { journey_session.reload.answers.subject } - .from("physics") - .to(nil) - ) - .and( - change { journey_session.reload.answers.visa_type } - .from("British National (Overseas) visa_type") - .to(nil) - ) - ) - end - end - - context "when the value hasn't changed" do - let(:existing_option) { option } - - it "doesn't reset dependent answers if the value hasn't changed" do - expect { expect(form.save).to be(true) }.to( - not_change { journey_session.reload.answers.state_funded_secondary_school } - .and(not_change { journey_session.reload.answers.one_year }) - .and(not_change { journey_session.reload.answers.start_date }) - .and(not_change { journey_session.reload.answers.subject }) - .and(not_change { journey_session.reload.answers.visa_type }) - ) - end - end - end end end diff --git a/spec/forms/journeys/get_a_teacher_relocation_payment/subject_form_spec.rb b/spec/forms/journeys/get_a_teacher_relocation_payment/subject_form_spec.rb index df57af9237..841287a018 100644 --- a/spec/forms/journeys/get_a_teacher_relocation_payment/subject_form_spec.rb +++ b/spec/forms/journeys/get_a_teacher_relocation_payment/subject_form_spec.rb @@ -36,20 +36,10 @@ describe "#available_options" do subject { form.available_options } - context "when a teacher" do - before { journey_session.answers.application_route = "teacher" } - - it do - is_expected.to( - match_array(%w[physics combined_with_physics languages other]) - ) - end - end - - context "when a trainee" do - before { journey_session.answers.application_route = "salaried_trainee" } - - it { is_expected.to(match_array(%w[physics languages other])) } + it do + is_expected.to( + match_array(%w[physics combined_with_physics languages other]) + ) end end diff --git a/spec/forms/journeys/get_a_teacher_relocation_payment/trainee_details_form_spec.rb b/spec/forms/journeys/get_a_teacher_relocation_payment/trainee_details_form_spec.rb deleted file mode 100644 index a8aa3e29a1..0000000000 --- a/spec/forms/journeys/get_a_teacher_relocation_payment/trainee_details_form_spec.rb +++ /dev/null @@ -1,46 +0,0 @@ -require "rails_helper" - -RSpec.describe Journeys::GetATeacherRelocationPayment::TraineeDetailsForm, type: :model do - let(:journey_session) { create(:get_a_teacher_relocation_payment_session) } - - let(:params) do - ActionController::Parameters.new( - claim: { - state_funded_secondary_school: option - } - ) - end - - let(:form) do - described_class.new( - journey_session: journey_session, - journey: Journeys::GetATeacherRelocationPayment, - params: params - ) - end - - describe "validations" do - subject { form } - - let(:option) { nil } - - it do - is_expected.not_to( - allow_value(nil) - .for(:state_funded_secondary_school) - .with_message("Select the option that applies to you") - ) - end - end - - describe "#save" do - let(:option) { true } - - it "updates the journey session" do - expect { expect(form.save).to be(true) }.to( - change { journey_session.reload.answers.state_funded_secondary_school } - .to(true) - ) - 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 5c1d61be6a..602e1cb623 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 @@ -10,90 +10,51 @@ describe "#eligibility_answers" do subject { presenter.eligibility_answers } - context "when a teacher application" do - let(:answers) do - build( - :get_a_teacher_relocation_payment_answers, - :with_teacher_application_route, - :with_state_funded_secondary_school, - :with_one_year_contract, - :with_start_date, - :with_subject, - :with_visa - ) - end - - it do - is_expected.to include( - [ - "What is your employment status?", - "I am employed as a teacher in a school in England", - "application-route" - ], - [ - "Are you employed by an English state secondary school?", - "Yes", - "state-funded-secondary-school" - ], - [ - "Are you employed on a contract lasting at least one year?", - "Yes", - "contract-details" - ], - [ - "Enter the start date of your contract", - answers.start_date.strftime("%d-%m-%Y"), - "start-date" - ], - [ - "What subject are you employed to teach at your school?", - "Physics", - "subject" - ], - [ - "Select the visa you used to move to England", - "British National (Overseas) visa", - "visa" - ] - ) - end + let(:answers) do + build( + :get_a_teacher_relocation_payment_answers, + :with_teacher_application_route, + :with_state_funded_secondary_school, + :with_one_year_contract, + :with_start_date, + :with_subject, + :with_visa + ) end - context "when a trainee application" do - let(:answers) do - build( - :get_a_teacher_relocation_payment_answers, - :with_trainee_application_route, - :with_state_funded_secondary_school, - :with_start_date, - :with_subject - ) - end - - it do - is_expected.to include( - [ - "What is your employment status?", - "I am enrolled on a salaried teacher training course in England", - "application-route" - ], - [ - "Are you on a teacher training course in England which meets the following conditions?", - "Yes", - "trainee-details" - ], - [ - "Enter the start date of your contract", - answers.start_date.strftime("%d-%m-%Y"), - "start-date" - ], - [ - "What subject are you training to teach?", - "Physics", - "subject" - ] - ) - end + it do + is_expected.to include( + [ + "What is your employment status?", + "I am employed as a teacher in a school in England", + "application-route" + ], + [ + "Are you employed by an English state secondary school?", + "Yes", + "state-funded-secondary-school" + ], + [ + "Are you employed on a contract lasting at least one year?", + "Yes", + "contract-details" + ], + [ + "Enter the start date of your contract", + answers.start_date.strftime("%d-%m-%Y"), + "start-date" + ], + [ + "What subject are you employed to teach at your school?", + "Physics", + "subject" + ], + [ + "Select the visa you used to move to England", + "British National (Overseas) visa", + "visa" + ] + ) end end end diff --git a/spec/models/policies/international_relocation_payments/policy_eligibility_checker_spec.rb b/spec/models/policies/international_relocation_payments/policy_eligibility_checker_spec.rb index c12c675f3d..0a07362e28 100644 --- a/spec/models/policies/international_relocation_payments/policy_eligibility_checker_spec.rb +++ b/spec/models/policies/international_relocation_payments/policy_eligibility_checker_spec.rb @@ -28,7 +28,7 @@ context "when the application route is 'salaried_trainee'" do let(:application_route) { "salaried_trainee" } - it { is_expected.to eq(:eligible_now) } + it { is_expected.to eq(:ineligible) } end end @@ -50,7 +50,7 @@ context "when the application route is 'salaried_trainee'" do let(:application_route) { "salaried_trainee" } - it { is_expected.to eq(false) } + it { is_expected.to eq(true) } end end 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 6aa00a0e06..7fda3efbd9 100644 --- a/spec/support/get_a_teacher_relocation_payment/step_helpers.rb +++ b/spec/support/get_a_teacher_relocation_payment/step_helpers.rb @@ -49,14 +49,6 @@ def and_i_complete_the_state_funded_secondary_school_step_with(option:) click_button("Continue") end - def and_i_complete_the_trainee_details_step_with(option:) - assert_on_trainee_details_page! - - choose(option) - - click_button("Continue") - end - def and_i_complete_the_contract_details_step_with(option:) assert_on_contract_details_page! @@ -75,8 +67,8 @@ def and_i_complete_the_contract_start_date_step_with(date:) click_button("Continue") end - def and_i_complete_the_subject_step_with(option:, trainee: false) - assert_on_subject_page!(trainee) + def and_i_complete_the_subject_step_with(option:) + assert_on_subject_page! choose(option) @@ -105,12 +97,6 @@ def assert_on_state_funded_secondary_school_page! ) end - def assert_on_trainee_details_page! - expect(page).to have_text( - "Are you on a teacher training course in England which meets the following conditions?" - ) - end - def assert_on_check_your_answers_part_one_page! expect(page).to have_text("Check your answers") end @@ -127,14 +113,10 @@ def assert_on_contract_start_date_page! expect(page).to have_text("Enter the start date of your contract") end - def assert_on_subject_page!(trainee) - if trainee - expect(page).to have_text("What subject are you training to teach?") - else - expect(page).to have_text( - "What subject are you employed to teach at your school?" - ) - end + def assert_on_subject_page! + expect(page).to have_text( + "What subject are you employed to teach at your school?" + ) end def assert_on_visa_page! From a92f8efe4cc047883e3285efe3c0cf04d890564f Mon Sep 17 00:00:00 2001 From: Richard Lynch Date: Fri, 21 Jun 2024 21:14:51 +0100 Subject: [PATCH 03/66] Adds the entry date form As in claim the entry date form writes to the date_of_entry attribute. We also reset the date of entry if the start date changes as the eligibility calculation for date of entry depends on the start date. Of note there doesn't seem to be a validation in claim that the date of entry isn't _after_ the start date of the contract. I'm not sure if that's a business rule we want to enforce or not. There is a validation that the date of entry isn't in the future. --- .../entry_date_form.rb | 38 +++++++ .../start_date_form.rb | 10 ++ .../get_a_teacher_relocation_payment.rb | 3 +- .../answers_presenter.rb | 9 ++ .../session_answers.rb | 1 + .../slug_sequence.rb | 1 + .../policy_eligibility_checker.rb | 8 ++ .../claims/entry_date.html.erb | 30 ++++++ config/analytics.yml | 1 + config/locales/en.yml | 6 ++ ...ional_relocation_payments_eligibilities.rb | 5 + db/schema.rb | 3 +- ...et_a_teacher_relocation_payment_answers.rb | 6 ++ ...eligible_route_completing_the_form_spec.rb | 18 ++++ .../teacher_route_completing_the_form_spec.rb | 9 ++ .../entry_date_form_spec.rb | 102 ++++++++++++++++++ .../start_date_form_spec.rb | 29 +++++ .../answers_presenter_spec.rb | 8 +- .../step_helpers.rb | 16 +++ 19 files changed, 300 insertions(+), 3 deletions(-) create mode 100644 app/forms/journeys/get_a_teacher_relocation_payment/entry_date_form.rb create mode 100644 app/views/get_a_teacher_relocation_payment/claims/entry_date.html.erb create mode 100644 db/migrate/20240621200501_add_date_of_entry_to_international_relocation_payments_eligibilities.rb create mode 100644 spec/forms/journeys/get_a_teacher_relocation_payment/entry_date_form_spec.rb 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( From 0d76fa92858068a51fccb3de166f810c15a1445b Mon Sep 17 00:00:00 2001 From: Richard Lynch Date: Mon, 24 Jun 2024 11:33:05 +0100 Subject: [PATCH 04/66] Add nationality screen We want to display the nationality in the personal details section of the journey. However claim's don't have a column for nationality, and as we're using the claim for shared details between journeys, we've decided to write the nationality to the eligibility column, even though it's not part of the eligibility criteria. We've added a new initializer to store the available nationality options, even though the list is only used in the form it's a bit awkward keeping it in there, and an initializer was the approach taken in the original IRP app. --- .../nationality_form.rb | 25 ++ .../get_a_teacher_relocation_payment.rb | 3 +- .../answers_presenter.rb | 14 ++ .../session_answers.rb | 1 + .../slug_sequence.rb | 6 +- .../claims/check_your_answers.html.erb | 8 + .../claims/nationality.html.erb | 37 +++ config/analytics.yml | 1 + config/initializers/nationalities.rb | 228 ++++++++++++++++++ config/locales/en.yml | 4 + ...ional_relocation_payments_eligibilities.rb | 5 + db/schema.rb | 3 +- scratch | 0 ...et_a_teacher_relocation_payment_answers.rb | 4 + .../teacher_route_completing_the_form_spec.rb | 6 + .../nationality_form_spec.rb | 46 ++++ .../answers_presenter_spec.rb | 24 +- .../step_helpers.rb | 12 + 18 files changed, 423 insertions(+), 4 deletions(-) create mode 100644 app/forms/journeys/get_a_teacher_relocation_payment/nationality_form.rb create mode 100644 app/views/get_a_teacher_relocation_payment/claims/nationality.html.erb create mode 100644 config/initializers/nationalities.rb create mode 100644 db/migrate/20240624102011_add_nationality_to_international_relocation_payments_eligibilities.rb create mode 100644 scratch create mode 100644 spec/forms/journeys/get_a_teacher_relocation_payment/nationality_form_spec.rb diff --git a/app/forms/journeys/get_a_teacher_relocation_payment/nationality_form.rb b/app/forms/journeys/get_a_teacher_relocation_payment/nationality_form.rb new file mode 100644 index 0000000000..c425f4c585 --- /dev/null +++ b/app/forms/journeys/get_a_teacher_relocation_payment/nationality_form.rb @@ -0,0 +1,25 @@ +module Journeys + module GetATeacherRelocationPayment + class NationalityForm < Form + attribute :nationality, :string + + validates :nationality, + inclusion: { + in: NATIONALITIES, + message: i18n_error_message(:inclusion) + } + + def available_options + NATIONALITIES + end + + def save + return false unless valid? + + journey_session.answers.assign_attributes(nationality: nationality) + + journey_session.save! + 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 16d87fb549..f572a42596 100644 --- a/app/models/journeys/get_a_teacher_relocation_payment.rb +++ b/app/models/journeys/get_a_teacher_relocation_payment.rb @@ -15,7 +15,8 @@ module GetATeacherRelocationPayment "start-date" => StartDateForm, "subject" => SubjectForm, "visa" => VisaForm, - "entry-date" => EntryDateForm + "entry-date" => EntryDateForm, + "nationality" => NationalityForm } } 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 d660e21cdf..570aecdadb 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 @@ -15,6 +15,12 @@ def eligibility_answers end.compact end + def identity_answers + super.tap do |a| + a << nationality + end + end + private def application_route @@ -72,6 +78,14 @@ def entry_date "entry-date" ] end + + def nationality + [ + t("get_a_teacher_relocation_payment.forms.nationality.question"), + answers.nationality, + "nationality" + ] + 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 8af21f834f..afdb8e0c1f 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 @@ -8,6 +8,7 @@ class SessionAnswers < Journeys::SessionAnswers attribute :subject, :string attribute :visa_type, :string attribute :date_of_entry, :date + attribute :nationality, :string 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 1419a891f6..45c0fcbd9f 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 @@ -12,12 +12,16 @@ class SlugSequence "check-your-answers-part-one" ] + PERSONAL_DETAILS_SLUGS = [ + "nationality", + ] + RESULTS_SLUGS = [ "check-your-answers", "ineligible" ].freeze - SLUGS = ELIGIBILITY_SLUGS + RESULTS_SLUGS + SLUGS = ELIGIBILITY_SLUGS + PERSONAL_DETAILS_SLUGS + RESULTS_SLUGS def self.start_page_url if Rails.env.production? diff --git a/app/views/get_a_teacher_relocation_payment/claims/check_your_answers.html.erb b/app/views/get_a_teacher_relocation_payment/claims/check_your_answers.html.erb index aeb6d5e340..470c79b3d6 100644 --- a/app/views/get_a_teacher_relocation_payment/claims/check_your_answers.html.erb +++ b/app/views/get_a_teacher_relocation_payment/claims/check_your_answers.html.erb @@ -15,6 +15,14 @@ <%= form_for @form, url: claim_submission_path, method: :post, builder: GOVUKDesignSystemFormBuilder::FormBuilder do |f| %> <%= f.govuk_error_summary %> + <%= render( + partial: "claims/check_your_answers_section", + locals: { + heading: "Identity details", + answers: journey.answers_for_claim(@form.journey_session).identity_answers + } + ) %> +

<%= t("check_your_answers.heading_send_application") %>

<%= t("check_your_answers.statement") %>

diff --git a/app/views/get_a_teacher_relocation_payment/claims/nationality.html.erb b/app/views/get_a_teacher_relocation_payment/claims/nationality.html.erb new file mode 100644 index 0000000000..e883629979 --- /dev/null +++ b/app/views/get_a_teacher_relocation_payment/claims/nationality.html.erb @@ -0,0 +1,37 @@ +<% content_for( + :page_title, + page_title( + t("get_a_teacher_relocation_payment.forms.nationality.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| %> + <%= f.govuk_error_summary %> + + <%= f.govuk_collection_select( + :nationality, + f.object.available_options, + :to_s, + :to_s, + label: { + text: t("get_a_teacher_relocation_payment.forms.nationality.question"), + size: "l" + }, + options: { + include_blank: true + } + ) %> + + <%= f.govuk_submit %> + <% end %> +
+
+ + diff --git a/config/analytics.yml b/config/analytics.yml index 2f7af2317e..1f02b9d51d 100644 --- a/config/analytics.yml +++ b/config/analytics.yml @@ -199,6 +199,7 @@ shared: - subject - visa_type - date_of_entry + - nationality :schools: - id - urn diff --git a/config/initializers/nationalities.rb b/config/initializers/nationalities.rb new file mode 100644 index 0000000000..3cb9537b44 --- /dev/null +++ b/config/initializers/nationalities.rb @@ -0,0 +1,228 @@ +# Taken from https://www.gov.uk/government/publications/nationalities +NATIONALITIES = [ + "Albanian", + "Afghan", + "Algerian", + "American", + "Andorran", + "Angolan", + "Anguillan", + "Argentine", + "Armenian", + "Australian", + "Austrian", + "Azerbaijani", + "Bahamian", + "Bahraini", + "Bangladeshi", + "Barbadian", + "Belarusian", + "Belgian", + "Belizean", + "Beninese", + "Bermudian", + "Bhutanese", + "Bolivian", + "Botswanan", + "Brazilian", + "British dependent Territories Citizen", + "British National Overseas", + "British Overseas Citizen", + "British Protected Person", + "British Virgin Islander", + "Bruneian", + "Bulgarian", + "Burkinan", + "Burmese", + "Burundian", + "Cambodian", + "Cameroonian", + "Canadian", + "Cape Verdean", + "Cayman Islander", + "Central African", + "Chadian", + "Chilean", + "Chinese", + "Citizen of Antigua and Barbuda", + "Citizen of Bosnia and Herzegovina", + "Citizen of Guinea-Bissau", + "Citizen of Kiribati", + "Citizen of Seychelles", + "Citizen of the Dominican Republic", + "Citizen of Vanuatu", + "Colombian", + "Comoran", + "Congolese (Congo)", + "Congolese (DRC)", + "Cook Islander", + "Costa Rican", + "Croatian", + "Cuban", + "Cypriot", + "Cymraes", + "Cymro", + "Czech", + "Danish", + "Djiboutian", + "Dominican", + "Dutch", + "East Timorese", + "Ecuadorean", + "Egyptian", + "Emirati", + "Equatorial Guinean", + "Eritrean", + "Estonian", + "Ethiopian", + "Faroese", + "Fijian", + "Filipino", + "Finnish", + "French", + "Gabonese", + "Gambian", + "Georgian", + "German", + "Ghanaian", + "Gibraltarian", + "Greek", + "Greenlandic", + "Grenadian", + "Guamanian", + "Guatemalan", + "Guinean", + "Guyanese", + "Haitian", + "Honduran", + "Hong Konger", + "Hungarian", + "Icelandic", + "Indian", + "Indonesian", + "Iranian", + "Iraqi", + "Irish", + "Israeli", + "Italian", + "Ivorian", + "Jamaican", + "Japanese", + "Jordanian", + "Kazakh", + "Kenyan", + "Kittitian", + "Kosovan", + "Kuwaiti", + "Kyrgyz", + "Lao", + "Latvian", + "Lebanese", + "Lesotho", + "Liberian", + "Libyan", + "Liechtenstein citizen", + "Lithuanian", + "Luxembourger", + "Macanese", + "Macedonian", + "Malagasy", + "Malawian", + "Malaysian", + "Maldivian", + "Malian", + "Maltese", + "Marshallese", + "Martiniquais", + "Mauritanian", + "Mauritian", + "Mexican", + "Micronesian", + "Moldovan", + "Monegasque", + "Mongolian", + "Montenegrin", + "Montserratian", + "Moroccan", + "Mosotho", + "Mozambican", + "Namibian", + "Nauruan", + "Nepalese", + "New Zealander", + "Nicaraguan", + "Nigerian", + "Nigerien", + "Niuean", + "North Korean", + "Northern Irish", + "Norwegian", + "Omani", + "Pakistani", + "Palauan", + "Palestinian", + "Panamanian", + "Papua New Guinean", + "Paraguayan", + "Peruvian", + "Pitcairn Islander", + "Polish", + "Portuguese", + "Prydeinig", + "Puerto Rican", + "Qatari", + "Romanian", + "Russian", + "Rwandan", + "Salvadorean", + "Sammarinese", + "Samoan", + "Sao Tomean", + "Saudi Arabian", + "Senegalese", + "Serbian", + "Sierra Leonean", + "Singaporean", + "Slovak", + "Slovenian", + "Solomon Islander", + "Somali", + "South African", + "South Korean", + "South Sudanese", + "Spanish", + "Sri Lankan", + "St Helenian", + "St Lucian", + "Sudanese", + "Surinamese", + "Swazi", + "Swedish", + "Syrian", + "Swiss", + "Tajik", + "Taiwanese", + "Thai", + "Tanzanian", + "Tongan", + "Togolese", + "Tristanian", + "Trinidadian", + "Turkish", + "Tunisian", + "Turks and Caicos Islander", + "Turkmen", + "Ugandan", + "Tuvaluan", + "Uruguayan", + "Ukrainian", + "Vatican citizen", + "Uzbek", + "Vietnamese", + "Venezuelan", + "Wallisian", + "Vincentian", + "Yemeni", + "Zimbabwean", + "Zambian" +].freeze diff --git a/config/locales/en.yml b/config/locales/en.yml index 105dba80bb..0cf8e53ad0 100644 --- a/config/locales/en.yml +++ b/config/locales/en.yml @@ -740,6 +740,10 @@ en: errors: presence: "Enter your entry date" date_not_in_future: "Date of entry cannot be in the future" + nationality: + question: "Select your nationality" + errors: + inclusion: "Choose your nationality" check_your_answers: diff --git a/db/migrate/20240624102011_add_nationality_to_international_relocation_payments_eligibilities.rb b/db/migrate/20240624102011_add_nationality_to_international_relocation_payments_eligibilities.rb new file mode 100644 index 0000000000..3056730abf --- /dev/null +++ b/db/migrate/20240624102011_add_nationality_to_international_relocation_payments_eligibilities.rb @@ -0,0 +1,5 @@ +class AddNationalityToInternationalRelocationPaymentsEligibilities < ActiveRecord::Migration[7.0] + def change + add_column :international_relocation_payments_eligibilities, :nationality, :string + end +end diff --git a/db/schema.rb b/db/schema.rb index 2e7e7a70dd..8f0afa50f1 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_200501) do +ActiveRecord::Schema[7.0].define(version: 2024_06_24_102011) do # These are extensions that must be enabled in order to support this database enable_extension "pg_trgm" enable_extension "pgcrypto" @@ -195,6 +195,7 @@ t.string "subject" t.string "visa_type" t.date "date_of_entry" + t.string "nationality" end create_table "journey_configurations", primary_key: "routing_name", id: :string, force: :cascade do |t| diff --git a/scratch b/scratch new file mode 100644 index 0000000000..e69de29bb2 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 d526c3a141..359eb0f1ad 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 @@ -40,6 +40,10 @@ date_of_entry { start_date - 1.week } end + trait :with_nationality do + nationality { "Australian" } + end + trait :with_email_details do email_address { generate(:email_address) } email_verified { true } 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 e7b13e3b6f..9297a5ccd3 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 @@ -35,7 +35,9 @@ 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_i_complete_the_nationality_step_with(option: "Australian") and_the_personal_details_section_has_been_temporarily_stubbed + then_the_check_your_answers_part_page_shows_my_answers and_i_submit_the_application then_the_application_is_submitted_successfully end @@ -72,4 +74,8 @@ def then_the_check_your_answers_part_one_page_shows_my_answers "Enter the date you moved to England to start your teaching job #{entry_date.strftime("%d-%m-%Y")}" ) end + + def then_the_check_your_answers_part_page_shows_my_answers + expect(page).to have_text("Select your nationality Australian") + end end diff --git a/spec/forms/journeys/get_a_teacher_relocation_payment/nationality_form_spec.rb b/spec/forms/journeys/get_a_teacher_relocation_payment/nationality_form_spec.rb new file mode 100644 index 0000000000..4a48d84711 --- /dev/null +++ b/spec/forms/journeys/get_a_teacher_relocation_payment/nationality_form_spec.rb @@ -0,0 +1,46 @@ +require "rails_helper" + +RSpec.describe Journeys::GetATeacherRelocationPayment::NationalityForm, type: :model do + let(:journey_session) { create(:get_a_teacher_relocation_payment_session) } + + let(:params) do + ActionController::Parameters.new( + claim: { + nationality: option + } + ) + end + + let(:option) { nil } + + let(:form) do + described_class.new( + journey_session: journey_session, + journey: Journeys::GetATeacherRelocationPayment, + params: params + ) + end + + describe "validations" do + subject { form } + + it do + is_expected.to( + validate_inclusion_of(:nationality) + .in_array(NATIONALITIES) + .with_message("Choose your nationality") + ) + end + end + + describe "#save" do + let(:option) { "Australian" } + + it "updates the journey session" do + expect { expect(form.save).to be(true) }.to( + change { journey_session.reload.answers.nationality } + .to("Australian") + ) + 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 e4ac7233a8..ba7f7fa85e 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 @@ -19,7 +19,8 @@ :with_start_date, :with_subject, :with_visa, - :with_entry_date + :with_entry_date, + :with_nationality ) end @@ -63,4 +64,25 @@ ) end end + + describe "#identity_answers" do + subject { presenter.identity_answers } + + let(:answers) do + build( + :get_a_teacher_relocation_payment_answers, + :with_nationality + ) + end + + it do + is_expected.to include( + [ + "Select your nationality", + "Australian", + "nationality" + ] + ) + end + end 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 4dc03d9612..3d14b2d4cd 100644 --- a/spec/support/get_a_teacher_relocation_payment/step_helpers.rb +++ b/spec/support/get_a_teacher_relocation_payment/step_helpers.rb @@ -97,6 +97,14 @@ def and_i_dont_change_my_answers click_button("Continue") end + def and_i_complete_the_nationality_step_with(option:) + assert_on_nationality_page! + + select(option) + + click_button("Continue") + end + def then_the_application_is_submitted_successfully assert_application_is_submitted! end @@ -139,6 +147,10 @@ def assert_on_entry_date_page! ) end + def assert_on_nationality_page! + expect(page).to have_text("Select your nationality") + end + def assert_application_is_submitted! expect(page).to have_content("Claim submitted") expect(page).to have_content( From 02e7bab0fcd73f8bf273a0ccd1c93000858baf8c Mon Sep 17 00:00:00 2001 From: Richard Lynch Date: Mon, 24 Jun 2024 12:13:37 +0100 Subject: [PATCH 05/66] Add the passport number screen Adds a screen for the passport number. Again like, the nationality, this is a question we show in the personal details part of the journey but we store it on the eligiblity, as this is the only journey that asks this question and the claim is shared with all journeys. --- .../passport_number_form.rb | 26 +++++++ .../get_a_teacher_relocation_payment.rb | 3 +- .../answers_presenter.rb | 9 +++ .../session_answers.rb | 1 + .../slug_sequence.rb | 1 + .../claims/passport_number.html.erb | 30 ++++++++ config/analytics_blocklist.yml | 2 + config/locales/en.yml | 5 ++ ...ional_relocation_payments_eligibilities.rb | 5 ++ db/schema.rb | 3 +- ...et_a_teacher_relocation_payment_answers.rb | 4 ++ .../teacher_route_completing_the_form_spec.rb | 5 ++ .../passport_number_form_spec.rb | 70 +++++++++++++++++++ .../answers_presenter_spec.rb | 8 ++- .../step_helpers.rb | 17 +++++ 15 files changed, 186 insertions(+), 3 deletions(-) create mode 100644 app/forms/journeys/get_a_teacher_relocation_payment/passport_number_form.rb create mode 100644 app/views/get_a_teacher_relocation_payment/claims/passport_number.html.erb create mode 100644 db/migrate/20240624105924_add_passport_number_to_international_relocation_payments_eligibilities.rb create mode 100644 spec/forms/journeys/get_a_teacher_relocation_payment/passport_number_form_spec.rb diff --git a/app/forms/journeys/get_a_teacher_relocation_payment/passport_number_form.rb b/app/forms/journeys/get_a_teacher_relocation_payment/passport_number_form.rb new file mode 100644 index 0000000000..7d07441d05 --- /dev/null +++ b/app/forms/journeys/get_a_teacher_relocation_payment/passport_number_form.rb @@ -0,0 +1,26 @@ +module Journeys + module GetATeacherRelocationPayment + class PassportNumberForm < Form + attribute :passport_number, :string + + validates :passport_number, presence: { + message: i18n_error_message(:presence) + } + + validates :passport_number, format: { + with: /\A[a-zA-Z0-9]{1,20}\z/, + message: i18n_error_message(:invalid) + }, if: :passport_number + + def save + return false unless valid? + + journey_session.answers.assign_attributes( + passport_number: passport_number + ) + + journey_session.save! + 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 f572a42596..4a6157eb03 100644 --- a/app/models/journeys/get_a_teacher_relocation_payment.rb +++ b/app/models/journeys/get_a_teacher_relocation_payment.rb @@ -16,7 +16,8 @@ module GetATeacherRelocationPayment "subject" => SubjectForm, "visa" => VisaForm, "entry-date" => EntryDateForm, - "nationality" => NationalityForm + "nationality" => NationalityForm, + "passport-number" => PassportNumberForm } } 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 570aecdadb..ab1b813591 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 @@ -18,6 +18,7 @@ def eligibility_answers def identity_answers super.tap do |a| a << nationality + a << passport_number end end @@ -86,6 +87,14 @@ def nationality "nationality" ] end + + def passport_number + [ + t("get_a_teacher_relocation_payment.forms.passport_number.question"), + answers.passport_number, + "passport-number" + ] + 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 afdb8e0c1f..82d5342db2 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 @@ -9,6 +9,7 @@ class SessionAnswers < Journeys::SessionAnswers attribute :visa_type, :string attribute :date_of_entry, :date attribute :nationality, :string + attribute :passport_number, :string 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 45c0fcbd9f..8251cb3ce2 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 @@ -14,6 +14,7 @@ class SlugSequence PERSONAL_DETAILS_SLUGS = [ "nationality", + "passport-number" ] RESULTS_SLUGS = [ diff --git a/app/views/get_a_teacher_relocation_payment/claims/passport_number.html.erb b/app/views/get_a_teacher_relocation_payment/claims/passport_number.html.erb new file mode 100644 index 0000000000..4c2b540106 --- /dev/null +++ b/app/views/get_a_teacher_relocation_payment/claims/passport_number.html.erb @@ -0,0 +1,30 @@ +<% content_for( + :page_title, + page_title( + t("get_a_teacher_relocation_payment.forms.passport_number.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| %> + <%= f.govuk_error_summary %> + + <%= f.govuk_text_field( + :passport_number, + label: { + text: t("get_a_teacher_relocation_payment.forms.passport_number.question"), + size: "l" + }, + ) %> + + <%= f.govuk_submit %> + <% end %> +
+
+ diff --git a/config/analytics_blocklist.yml b/config/analytics_blocklist.yml index d6fc7730b1..f50bb151b0 100644 --- a/config/analytics_blocklist.yml +++ b/config/analytics_blocklist.yml @@ -96,4 +96,6 @@ - created_at - updated_at - gender_digit + :international_relocation_payments_eligibilities: + - passport_number diff --git a/config/locales/en.yml b/config/locales/en.yml index 0cf8e53ad0..2aa6641658 100644 --- a/config/locales/en.yml +++ b/config/locales/en.yml @@ -744,6 +744,11 @@ en: question: "Select your nationality" errors: inclusion: "Choose your nationality" + passport_number: + question: "Enter your passport number, as it appears on your passport" + errors: + presence: "Enter your passport number" + invalid: "Invalid passport number" check_your_answers: diff --git a/db/migrate/20240624105924_add_passport_number_to_international_relocation_payments_eligibilities.rb b/db/migrate/20240624105924_add_passport_number_to_international_relocation_payments_eligibilities.rb new file mode 100644 index 0000000000..9539c3b1a8 --- /dev/null +++ b/db/migrate/20240624105924_add_passport_number_to_international_relocation_payments_eligibilities.rb @@ -0,0 +1,5 @@ +class AddPassportNumberToInternationalRelocationPaymentsEligibilities < ActiveRecord::Migration[7.0] + def change + add_column :international_relocation_payments_eligibilities, :passport_number, :string + end +end diff --git a/db/schema.rb b/db/schema.rb index 8f0afa50f1..2bbacefc1c 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_24_102011) do +ActiveRecord::Schema[7.0].define(version: 2024_06_24_105924) do # These are extensions that must be enabled in order to support this database enable_extension "pg_trgm" enable_extension "pgcrypto" @@ -196,6 +196,7 @@ t.string "visa_type" t.date "date_of_entry" t.string "nationality" + t.string "passport_number" 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 359eb0f1ad..2ebd10b624 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 @@ -44,6 +44,10 @@ nationality { "Australian" } end + trait :with_passport_number do + passport_number { "1234567890123456789A" } + end + trait :with_email_details do email_address { generate(:email_address) } email_verified { true } 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 9297a5ccd3..1903fc728e 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 @@ -36,6 +36,7 @@ then_the_check_your_answers_part_one_page_shows_my_answers and_i_dont_change_my_answers and_i_complete_the_nationality_step_with(option: "Australian") + and_i_complete_the_passport_number_step_with(options: "123456789") and_the_personal_details_section_has_been_temporarily_stubbed then_the_check_your_answers_part_page_shows_my_answers and_i_submit_the_application @@ -77,5 +78,9 @@ def then_the_check_your_answers_part_one_page_shows_my_answers def then_the_check_your_answers_part_page_shows_my_answers expect(page).to have_text("Select your nationality Australian") + + expect(page).to have_text( + "Enter your passport number, as it appears on your passport 123456789" + ) end end diff --git a/spec/forms/journeys/get_a_teacher_relocation_payment/passport_number_form_spec.rb b/spec/forms/journeys/get_a_teacher_relocation_payment/passport_number_form_spec.rb new file mode 100644 index 0000000000..c2fa4198a9 --- /dev/null +++ b/spec/forms/journeys/get_a_teacher_relocation_payment/passport_number_form_spec.rb @@ -0,0 +1,70 @@ +require "rails_helper" + +RSpec.describe Journeys::GetATeacherRelocationPayment::PassportNumberForm, type: :model do + let(:journey_session) { create(:get_a_teacher_relocation_payment_session) } + + let(:params) do + ActionController::Parameters.new( + claim: { + passport_number: option + } + ) + end + + let(:option) { nil } + + let(:form) do + described_class.new( + journey_session: journey_session, + journey: Journeys::GetATeacherRelocationPayment, + params: params + ) + end + + describe "validations" do + subject { form } + + it do + is_expected.to( + validate_presence_of(:passport_number) + .with_message("Enter your passport number") + ) + end + + # Passport number contains non alphanumeric characters + it do + is_expected.not_to( + allow_value("123456789012345$") + .for(:passport_number) + .with_message("Invalid passport number") + ) + end + + # Passport number at max allowed length + it do + is_expected.to( + allow_value("1234567890ABCDEfghij").for(:passport_number) + ) + end + + # Passport number too long + it do + is_expected.not_to( + allow_value("12345678901234567890A") + .for(:passport_number) + .with_message("Invalid passport number") + ) + end + end + + describe "#save" do + let(:option) { "123456789012345" } + + it "updates the journey session" do + expect { expect(form.save).to be(true) }.to( + change { journey_session.reload.answers.passport_number } + .to("123456789012345") + ) + 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 ba7f7fa85e..7bf3d90938 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 @@ -71,7 +71,8 @@ let(:answers) do build( :get_a_teacher_relocation_payment_answers, - :with_nationality + :with_nationality, + :with_passport_number ) end @@ -81,6 +82,11 @@ "Select your nationality", "Australian", "nationality" + ], + [ + "Enter your passport number, as it appears on your passport", + "1234567890123456789A", + "passport-number" ] ) 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 3d14b2d4cd..cca8f9d390 100644 --- a/spec/support/get_a_teacher_relocation_payment/step_helpers.rb +++ b/spec/support/get_a_teacher_relocation_payment/step_helpers.rb @@ -105,6 +105,17 @@ def and_i_complete_the_nationality_step_with(option:) click_button("Continue") end + def and_i_complete_the_passport_number_step_with(options:) + assert_on_passport_number_page! + + fill_in( + "Enter your passport number, as it appears on your passport", + with: options + ) + + click_button("Continue") + end + def then_the_application_is_submitted_successfully assert_application_is_submitted! end @@ -151,6 +162,12 @@ def assert_on_nationality_page! expect(page).to have_text("Select your nationality") end + def assert_on_passport_number_page! + expect(page).to have_text( + "Enter your passport number, as it appears on your passport" + ) + end + def assert_application_is_submitted! expect(page).to have_content("Claim submitted") expect(page).to have_content( From 1f2e5c76f277b3089296df8fed41011374f59615 Mon Sep 17 00:00:00 2001 From: Richard Lynch Date: Mon, 24 Jun 2024 14:26:03 +0100 Subject: [PATCH 06/66] Add personal details screen Adds the personal details screen. This screen is already shared with other journeys so we just needed to update the slugs and fix one of the callbacks --- app/controllers/claims_form_callbacks.rb | 8 ++++++-- .../answers_student_loans_details_updater.rb | 6 ++++++ .../slug_sequence.rb | 3 ++- .../teacher_route_completing_the_form_spec.rb | 13 +++++++++++++ .../step_helpers.rb | 19 ++++++++++++++++++- 5 files changed, 45 insertions(+), 4 deletions(-) create mode 100644 app/models/journeys/get_a_teacher_relocation_payment/answers_student_loans_details_updater.rb diff --git a/app/controllers/claims_form_callbacks.rb b/app/controllers/claims_form_callbacks.rb index 1122f807c7..6ea3f6960d 100644 --- a/app/controllers/claims_form_callbacks.rb +++ b/app/controllers/claims_form_callbacks.rb @@ -38,7 +38,7 @@ def information_provided_before_update end def personal_details_after_form_save_success - return unless journey_requires_student_loan_details? + return redirect_to_next_slug unless journey_requires_student_loan_details? retrieve_student_loan_details redirect_to_next_slug @@ -115,7 +115,7 @@ def on_tid_route? end def journey_requires_student_loan_details? - student_loans_journey? || additional_payments_journey? + student_loans_journey? || additional_payments_journey? || get_a_teacher_relocation_payment_journey? end def student_loans_journey? @@ -125,4 +125,8 @@ def student_loans_journey? def additional_payments_journey? current_journey_routing_name == "additional-payments" end + + def get_a_teacher_relocation_payment_journey? + current_journey_routing_name == "get-a-teacher-relocation-payment" + end end diff --git a/app/models/journeys/get_a_teacher_relocation_payment/answers_student_loans_details_updater.rb b/app/models/journeys/get_a_teacher_relocation_payment/answers_student_loans_details_updater.rb new file mode 100644 index 0000000000..0e354e84e2 --- /dev/null +++ b/app/models/journeys/get_a_teacher_relocation_payment/answers_student_loans_details_updater.rb @@ -0,0 +1,6 @@ +module Journeys + module GetATeacherRelocationPayment + class AnswersStudentLoansDetailsUpdater < Journeys::AnswersStudentLoansDetailsUpdater + 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 8251cb3ce2..87e6fe86cd 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 @@ -14,7 +14,8 @@ class SlugSequence PERSONAL_DETAILS_SLUGS = [ "nationality", - "passport-number" + "passport-number", + "personal-details" ] RESULTS_SLUGS = [ 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 1903fc728e..10ce596c46 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 @@ -37,6 +37,7 @@ and_i_dont_change_my_answers and_i_complete_the_nationality_step_with(option: "Australian") and_i_complete_the_passport_number_step_with(options: "123456789") + and_i_complete_the_personal_details_step and_the_personal_details_section_has_been_temporarily_stubbed then_the_check_your_answers_part_page_shows_my_answers and_i_submit_the_application @@ -77,6 +78,18 @@ def then_the_check_your_answers_part_one_page_shows_my_answers end def then_the_check_your_answers_part_page_shows_my_answers + expect(page).to have_text( + "What is your full name? Walter Seymour Skinner" + ) + + expect(page).to have_text( + "What is your date of birth? 12 July 1945" + ) + + expect(page).to have_text( + "What is your National Insurance number? QQ123456C" + ) + expect(page).to have_text("Select your nationality Australian") expect(page).to have_text( 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 cca8f9d390..e132dd3732 100644 --- a/spec/support/get_a_teacher_relocation_payment/step_helpers.rb +++ b/spec/support/get_a_teacher_relocation_payment/step_helpers.rb @@ -23,7 +23,6 @@ def and_the_personal_details_section_has_been_temporarily_stubbed journey_session.answers.assign_attributes( attributes_for( :get_a_teacher_relocation_payment_answers, - :with_personal_details, :with_email_details, :with_mobile_details, :with_bank_details, @@ -116,6 +115,20 @@ def and_i_complete_the_passport_number_step_with(options:) click_button("Continue") end + def and_i_complete_the_personal_details_step + assert_on_personal_details_page! + + fill_in("First name", with: "Walter") + fill_in("Middle names", with: "Seymour") + fill_in("Last name", with: "Skinner") + fill_in("Day", with: "12") + fill_in("Month", with: "7") + fill_in("Year", with: "1945") + fill_in("What is your National Insurance number", with: "QQ123456C") + + click_button("Continue") + end + def then_the_application_is_submitted_successfully assert_application_is_submitted! end @@ -168,6 +181,10 @@ def assert_on_passport_number_page! ) end + def assert_on_personal_details_page! + expect(page).to have_text("What is your full name?") + end + def assert_application_is_submitted! expect(page).to have_content("Claim submitted") expect(page).to have_content( From 30790bab3f05d166ae011565bee858214b1381c4 Mon Sep 17 00:00:00 2001 From: Richard Lynch Date: Mon, 24 Jun 2024 15:31:26 +0100 Subject: [PATCH 07/66] Adds the postcode search form to irp Adds the ability to search by postcode and select an address. "postcode-search" was included in each journey's list of forms separately but this commit moves it up into the shared by module. --- .../additional_payments_for_teaching.rb | 1 - app/models/journeys/base.rb | 1 + .../slug_sequence.rb | 5 +- .../teacher_student_loan_reimbursement.rb | 1 - .../teacher_route_completing_the_form_spec.rb | 78 +++++++++++++------ .../step_helpers.rb | 47 +++++++++++ 6 files changed, 108 insertions(+), 25 deletions(-) diff --git a/app/models/journeys/additional_payments_for_teaching.rb b/app/models/journeys/additional_payments_for_teaching.rb index 6f71d4ecad..cb4563a7c2 100644 --- a/app/models/journeys/additional_payments_for_teaching.rb +++ b/app/models/journeys/additional_payments_for_teaching.rb @@ -26,7 +26,6 @@ module AdditionalPaymentsForTeaching "eligibility-confirmed" => EligibilityConfirmedForm, "correct-school" => CorrectSchoolForm, "reset-claim" => ResetClaimForm, - "postcode-search" => PostcodeSearchForm, "select-home-address" => SelectHomeAddressForm }, "reminders" => { diff --git a/app/models/journeys/base.rb b/app/models/journeys/base.rb index d584b24760..0884272cfc 100644 --- a/app/models/journeys/base.rb +++ b/app/models/journeys/base.rb @@ -18,6 +18,7 @@ module Base "building-society-account" => BankDetailsForm, "teacher-reference-number" => TeacherReferenceNumberForm, "address" => AddressForm, + "postcode-search" => PostcodeSearchForm, "select-home-address" => SelectHomeAddressForm, "check-your-answers" => CheckYourAnswersForm } 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 87e6fe86cd..b1f5c5bd1b 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 @@ -15,7 +15,10 @@ class SlugSequence PERSONAL_DETAILS_SLUGS = [ "nationality", "passport-number", - "personal-details" + "personal-details", + "postcode-search", + "select-home-address", + "address" ] RESULTS_SLUGS = [ diff --git a/app/models/journeys/teacher_student_loan_reimbursement.rb b/app/models/journeys/teacher_student_loan_reimbursement.rb index cf683369d0..f7b21ba3d3 100644 --- a/app/models/journeys/teacher_student_loan_reimbursement.rb +++ b/app/models/journeys/teacher_student_loan_reimbursement.rb @@ -20,7 +20,6 @@ module TeacherStudentLoanReimbursement "leadership-position" => LeadershipPositionForm, "mostly-performed-leadership-duties" => MostlyPerformedLeadershipDutiesForm, "reset-claim" => ResetClaimForm, - "postcode-search" => PostcodeSearchForm, "select-claim-school" => SelectClaimSchoolForm, "select-home-address" => SelectHomeAddressForm } 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 10ce596c46..7fbdf15b88 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 @@ -20,28 +20,58 @@ end describe "navigating forward" do - it "submits an application" 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: entry_date) - then_the_check_your_answers_part_one_page_shows_my_answers - and_i_dont_change_my_answers - and_i_complete_the_nationality_step_with(option: "Australian") - and_i_complete_the_passport_number_step_with(options: "123456789") - and_i_complete_the_personal_details_step - and_the_personal_details_section_has_been_temporarily_stubbed - then_the_check_your_answers_part_page_shows_my_answers - and_i_submit_the_application - then_the_application_is_submitted_successfully + context "with postcode search" do + it "submits an application" 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: entry_date) + then_the_check_your_answers_part_one_page_shows_my_answers + and_i_dont_change_my_answers + and_i_complete_the_nationality_step_with(option: "Australian") + and_i_complete_the_passport_number_step_with(options: "123456789") + and_i_complete_the_personal_details_step + and_i_complete_the_postcode_step + and_the_personal_details_section_has_been_temporarily_stubbed + then_the_check_your_answers_part_page_shows_my_answers + and_i_submit_the_application + then_the_application_is_submitted_successfully + end + end + + context "without postcode search" do + it "submits an application" 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: entry_date) + then_the_check_your_answers_part_one_page_shows_my_answers + and_i_dont_change_my_answers + and_i_complete_the_nationality_step_with(option: "Australian") + and_i_complete_the_passport_number_step_with(options: "123456789") + and_i_complete_the_personal_details_step + and_i_complete_the_manual_address_step + and_the_personal_details_section_has_been_temporarily_stubbed + then_the_check_your_answers_part_page_shows_my_answers + and_i_submit_the_application + then_the_application_is_submitted_successfully + end end end @@ -90,6 +120,10 @@ def then_the_check_your_answers_part_page_shows_my_answers "What is your National Insurance number? QQ123456C" ) + expect(page).to have_text( + "What is your address? Flat 1, Millbrook Tower, Windermere Avenue, Southampton, SO16 9FX" + ) + expect(page).to have_text("Select your nationality Australian") expect(page).to have_text( 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 e132dd3732..53a3f68b19 100644 --- a/spec/support/get_a_teacher_relocation_payment/step_helpers.rb +++ b/spec/support/get_a_teacher_relocation_payment/step_helpers.rb @@ -129,6 +129,49 @@ def and_i_complete_the_personal_details_step click_button("Continue") end + def and_i_complete_the_postcode_step + assert_on_postcode_page! + + allow_any_instance_of(OrdnanceSurvey::Client) + .to receive_message_chain(:api, :search_places, :index) + .and_return( + [ + { + address: "Flat 1, Millbrook Tower, Windermere Avenue, Southampton, SO16 9FX", + address_line_1: "FLAT 1, MILLBROOK TOWER", + address_line_2: "WINDERMERE AVENUE", + address_line_3: "SOUTHAMPTON", + postcode: "SO16 9FX" + } + ] + ) + + fill_in("Postcode", with: "SO16 9FX") + + click_on "Search" + + expect(page).to have_text("Select an address") + choose "flat_1_millbrook_tower_windermere_avenue_southampton_so16_9fx" + + click_on "Continue" + end + + def and_i_complete_the_manual_address_step + assert_on_postcode_page! + + click_link("Enter your address manually") + + fill_in("House number or name", with: "Flat 1, Millbrook Tower") + + fill_in("Building and street", with: "Windermere Avenue") + + fill_in("Town or city", with: "Southampton") + + fill_in("Postcode", with: "SO16 9FX") + + click_button("Continue") + end + def then_the_application_is_submitted_successfully assert_application_is_submitted! end @@ -185,6 +228,10 @@ def assert_on_personal_details_page! expect(page).to have_text("What is your full name?") end + def assert_on_postcode_page! + expect(page).to have_text("What is your home address?") + end + def assert_application_is_submitted! expect(page).to have_content("Claim submitted") expect(page).to have_content( From 9228da6889dc2f6294b8d37129f2714424ff2cde Mon Sep 17 00:00:00 2001 From: Richard Lynch Date: Mon, 24 Jun 2024 16:40:28 +0100 Subject: [PATCH 08/66] Adds the email verification step to IRP Enables the existing email forms for the IRP journey --- app/mailers/claim_mailer.rb | 7 ++++++- .../session_answers.rb | 4 ++++ .../slug_sequence.rb | 4 +++- .../international_relocation_payments.rb | 8 ++++++++ config/locales/en.yml | 9 ++++++--- .../teacher_route_completing_the_form_spec.rb | 6 ++++++ .../step_helpers.rb | 17 ++++++++++++++++- 7 files changed, 49 insertions(+), 6 deletions(-) diff --git a/app/mailers/claim_mailer.rb b/app/mailers/claim_mailer.rb index da3851b5e5..752a64fb95 100644 --- a/app/mailers/claim_mailer.rb +++ b/app/mailers/claim_mailer.rb @@ -97,7 +97,12 @@ def send_mail(template_id, personalisation) end def unknown_policy_check(claim) - return if [Policies::StudentLoans, Policies::EarlyCareerPayments, Policies::LevellingUpPremiumPayments].include?(claim.policy) + return if [ + Policies::StudentLoans, + Policies::EarlyCareerPayments, + Policies::LevellingUpPremiumPayments, + Policies::InternationalRelocationPayments + ].include?(claim.policy) raise ArgumentError, "Unknown claim policy: #{claim.policy}" 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 82d5342db2..db7ff32547 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 @@ -10,6 +10,10 @@ class SessionAnswers < Journeys::SessionAnswers attribute :date_of_entry, :date attribute :nationality, :string attribute :passport_number, :string + + def policy + Policies::InternationalRelocationPayments + end 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 b1f5c5bd1b..9e51528e98 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 @@ -18,7 +18,9 @@ class SlugSequence "personal-details", "postcode-search", "select-home-address", - "address" + "address", + "email-address", + "email-verification" ] RESULTS_SLUGS = [ diff --git a/app/models/policies/international_relocation_payments.rb b/app/models/policies/international_relocation_payments.rb index d2f50f836a..52d02a93ba 100644 --- a/app/models/policies/international_relocation_payments.rb +++ b/app/models/policies/international_relocation_payments.rb @@ -1,4 +1,12 @@ module Policies module InternationalRelocationPayments + include BasePolicy + extend self + + # NOTE RL: currently IRP only has a single reply to address, so notify + # doesn't show the address id + def notify_reply_to_id + nil + end end end diff --git a/config/locales/en.yml b/config/locales/en.yml index 2aa6641658..fe475c9927 100644 --- a/config/locales/en.yml +++ b/config/locales/en.yml @@ -679,10 +679,12 @@ en: claim_amount_description: "Additional payment for teaching" support_email_address: "levellinguppremiumpayments@digital.education.gov.uk" information_provided_further_details_link_text: levelling up premium payment (opens in new tab) - get_a_teacher_relocation_payment: + get_a_teacher_relocation_payment: &get_a_teacher_relocation_payment journey_name: "Get a teacher relocation payment" feedback_email: "teach.inengland@education.gov.uk" claim_description: "for a get a teacher relocation payment" + claim_subject: "International relocation payment" + support_email_address: "teach.inengland@education.gov.uk" forms: application_route: question: "What is your employment status?" @@ -749,14 +751,15 @@ en: errors: presence: "Enter your passport number" invalid: "Invalid passport number" - - check_your_answers: part_one: primary_heading: "Check your answers" eligibility_details: "Eligibility details" confirmation_notice: "By selecting continue you are confirming that, to the best of your knowledge, the details you are providing are correct." + international_relocation_payments: + <<: *get_a_teacher_relocation_payment + further_education_payments: landing_page: Find out if you are eligible for any incentive payments for further education teachers claim_description: for further education payments 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 7fbdf15b88..b030e6b235 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 @@ -40,6 +40,7 @@ and_i_complete_the_passport_number_step_with(options: "123456789") and_i_complete_the_personal_details_step and_i_complete_the_postcode_step + and_i_complete_the_email_address_step and_the_personal_details_section_has_been_temporarily_stubbed then_the_check_your_answers_part_page_shows_my_answers and_i_submit_the_application @@ -67,6 +68,7 @@ and_i_complete_the_passport_number_step_with(options: "123456789") and_i_complete_the_personal_details_step and_i_complete_the_manual_address_step + and_i_complete_the_email_address_step and_the_personal_details_section_has_been_temporarily_stubbed then_the_check_your_answers_part_page_shows_my_answers and_i_submit_the_application @@ -124,6 +126,10 @@ def then_the_check_your_answers_part_page_shows_my_answers "What is your address? Flat 1, Millbrook Tower, Windermere Avenue, Southampton, SO16 9FX" ) + expect(page).to have_text( + "Email address seymour.skinner@springfieldelementary.edu" + ) + expect(page).to have_text("Select your nationality Australian") expect(page).to have_text( 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 53a3f68b19..a300c5ce91 100644 --- a/spec/support/get_a_teacher_relocation_payment/step_helpers.rb +++ b/spec/support/get_a_teacher_relocation_payment/step_helpers.rb @@ -23,7 +23,6 @@ def and_the_personal_details_section_has_been_temporarily_stubbed journey_session.answers.assign_attributes( attributes_for( :get_a_teacher_relocation_payment_answers, - :with_email_details, :with_mobile_details, :with_bank_details, email_address: "test-irp-claim@example.com", @@ -172,6 +171,18 @@ def and_i_complete_the_manual_address_step click_button("Continue") end + def and_i_complete_the_email_address_step + assert_on_email_address_page! + + fill_in "Email address", with: "seymour.skinner@springfieldelementary.edu" + + click_on "Continue" + + fill_in "Enter the 6-digit passcode", with: get_otp_from_email + + click_on "Confirm" + end + def then_the_application_is_submitted_successfully assert_application_is_submitted! end @@ -232,6 +243,10 @@ def assert_on_postcode_page! expect(page).to have_text("What is your home address?") end + def assert_on_email_address_page! + expect(page).to have_text("Email address") + end + def assert_application_is_submitted! expect(page).to have_content("Claim submitted") expect(page).to have_content( From 3607271c7c2d776b06ad648cd51150a227fd6c44 Mon Sep 17 00:00:00 2001 From: Richard Lynch Date: Tue, 25 Jun 2024 09:49:27 +0100 Subject: [PATCH 09/66] Adds provide mobile number screen Not much to say about this one! --- .../slug_sequence.rb | 3 ++- .../teacher_route_completing_the_form_spec.rb | 6 ++++++ .../step_helpers.rb | 13 ++++++++++++- 3 files changed, 20 insertions(+), 2 deletions(-) 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 9e51528e98..f99a9b9295 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 @@ -20,7 +20,8 @@ class SlugSequence "select-home-address", "address", "email-address", - "email-verification" + "email-verification", + "provide-mobile-number" ] RESULTS_SLUGS = [ 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 b030e6b235..2a076a87ae 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 @@ -41,6 +41,7 @@ and_i_complete_the_personal_details_step and_i_complete_the_postcode_step and_i_complete_the_email_address_step + and_i_dont_provide_my_mobile_number and_the_personal_details_section_has_been_temporarily_stubbed then_the_check_your_answers_part_page_shows_my_answers and_i_submit_the_application @@ -69,6 +70,7 @@ and_i_complete_the_personal_details_step and_i_complete_the_manual_address_step and_i_complete_the_email_address_step + and_i_dont_provide_my_mobile_number and_the_personal_details_section_has_been_temporarily_stubbed then_the_check_your_answers_part_page_shows_my_answers and_i_submit_the_application @@ -135,5 +137,9 @@ def then_the_check_your_answers_part_page_shows_my_answers expect(page).to have_text( "Enter your passport number, as it appears on your passport 123456789" ) + + expect(page).to have_text( + "Would you like to provide your mobile number? No" + ) end 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 a300c5ce91..d5d9081dd8 100644 --- a/spec/support/get_a_teacher_relocation_payment/step_helpers.rb +++ b/spec/support/get_a_teacher_relocation_payment/step_helpers.rb @@ -23,7 +23,6 @@ def and_the_personal_details_section_has_been_temporarily_stubbed journey_session.answers.assign_attributes( attributes_for( :get_a_teacher_relocation_payment_answers, - :with_mobile_details, :with_bank_details, email_address: "test-irp-claim@example.com", teacher_reference_number: "1234567", @@ -183,6 +182,14 @@ def and_i_complete_the_email_address_step click_on "Confirm" end + def and_i_dont_provide_my_mobile_number + assert_on_provider_mobile_number_page! + + choose "No" + + click_button("Continue") + end + def then_the_application_is_submitted_successfully assert_application_is_submitted! end @@ -247,6 +254,10 @@ def assert_on_email_address_page! expect(page).to have_text("Email address") end + def assert_on_provider_mobile_number_page! + expect(page).to have_text("Would you like to provide your mobile number?") + end + def assert_application_is_submitted! expect(page).to have_content("Claim submitted") expect(page).to have_content( From a1a0d830badeb9f33ce06176fadfe4508c7a597d Mon Sep 17 00:00:00 2001 From: Richard Lynch Date: Tue, 25 Jun 2024 10:27:39 +0100 Subject: [PATCH 10/66] Adds the mobile verification page Again not much to say about this one! --- .../slug_sequence.rb | 11 ++++- .../teacher_route_completing_the_form_spec.rb | 41 +++++++++++++++++-- .../step_helpers.rb | 23 +++++++++++ 3 files changed, 69 insertions(+), 6 deletions(-) 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 f99a9b9295..0c7cc15962 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 @@ -21,7 +21,9 @@ class SlugSequence "address", "email-address", "email-verification", - "provide-mobile-number" + "provide-mobile-number", + "mobile-number", + "mobile-verification" ] RESULTS_SLUGS = [ @@ -48,7 +50,12 @@ def initialize(journey_session) end def slugs - SLUGS.dup + SLUGS.dup.tap do |sequence| + if answers.provide_mobile_number == false + sequence.delete("mobile-number") + sequence.delete("mobile-verification") + end + end end end end 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 2a076a87ae..f93dc7f22d 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 @@ -77,6 +77,35 @@ then_the_application_is_submitted_successfully end end + + context "with mobile verification" do + it "submits an application" 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: entry_date) + then_the_check_your_answers_part_one_page_shows_my_answers + and_i_dont_change_my_answers + and_i_complete_the_nationality_step_with(option: "Australian") + and_i_complete_the_passport_number_step_with(options: "123456789") + and_i_complete_the_personal_details_step + and_i_complete_the_manual_address_step + and_i_complete_the_email_address_step + and_i_provide_my_mobile_number + and_the_personal_details_section_has_been_temporarily_stubbed + then_the_check_your_answers_part_page_shows_my_answers(mobile_number: true) + and_i_submit_the_application + then_the_application_is_submitted_successfully + end + end end def then_the_check_your_answers_part_one_page_shows_my_answers @@ -111,7 +140,7 @@ def then_the_check_your_answers_part_one_page_shows_my_answers ) end - def then_the_check_your_answers_part_page_shows_my_answers + def then_the_check_your_answers_part_page_shows_my_answers(mobile_number: false) expect(page).to have_text( "What is your full name? Walter Seymour Skinner" ) @@ -138,8 +167,12 @@ def then_the_check_your_answers_part_page_shows_my_answers "Enter your passport number, as it appears on your passport 123456789" ) - expect(page).to have_text( - "Would you like to provide your mobile number? No" - ) + if mobile_number + expect(page).to have_text("Mobile number 01234567890") + else + expect(page).to have_text( + "Would you like to provide your mobile number? No" + ) + end end 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 d5d9081dd8..5a5159daac 100644 --- a/spec/support/get_a_teacher_relocation_payment/step_helpers.rb +++ b/spec/support/get_a_teacher_relocation_payment/step_helpers.rb @@ -190,6 +190,29 @@ def and_i_dont_provide_my_mobile_number click_button("Continue") end + def and_i_provide_my_mobile_number + assert_on_provider_mobile_number_page! + + choose "Yes" + + click_button("Continue") + + otp_code = nil + + allow(NotifySmsMessage).to( + receive(:new) { |args| otp_code = args.fetch(:personalisation).fetch(:otp) } + .and_return(double(NotifySmsMessage, deliver!: true)) + ) + + fill_in("Mobile number", with: "01234567890") + + click_button("Continue") + + fill_in("Enter the 6-digit passcode", with: otp_code) + + click_button "Confirm" + end + def then_the_application_is_submitted_successfully assert_application_is_submitted! end From c62efc79577c794fa1df3535e0ac1859a6b5912c Mon Sep 17 00:00:00 2001 From: Richard Lynch Date: Tue, 25 Jun 2024 10:31:04 +0100 Subject: [PATCH 11/66] Move eligibility questions to shared setup These tests are focused on the personal details section of the journey so we'll move the shared setup to a before hook so the differences in the scenarios stand out more. --- .../teacher_route_completing_the_form_spec.rb | 59 ++++++------------- 1 file changed, 17 insertions(+), 42 deletions(-) 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 f93dc7f22d..f863d3aaab 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 @@ -20,22 +20,25 @@ end describe "navigating forward" do + before 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: entry_date) + then_the_check_your_answers_part_one_page_shows_my_answers + and_i_dont_change_my_answers + end + context "with postcode search" do it "submits an application" 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: entry_date) - then_the_check_your_answers_part_one_page_shows_my_answers - and_i_dont_change_my_answers and_i_complete_the_nationality_step_with(option: "Australian") and_i_complete_the_passport_number_step_with(options: "123456789") and_i_complete_the_personal_details_step @@ -51,20 +54,6 @@ context "without postcode search" do it "submits an application" 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: entry_date) - then_the_check_your_answers_part_one_page_shows_my_answers - and_i_dont_change_my_answers and_i_complete_the_nationality_step_with(option: "Australian") and_i_complete_the_passport_number_step_with(options: "123456789") and_i_complete_the_personal_details_step @@ -80,20 +69,6 @@ context "with mobile verification" do it "submits an application" 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: entry_date) - then_the_check_your_answers_part_one_page_shows_my_answers - and_i_dont_change_my_answers and_i_complete_the_nationality_step_with(option: "Australian") and_i_complete_the_passport_number_step_with(options: "123456789") and_i_complete_the_personal_details_step From 137b0cf3f1c5c986c18059b0b97e3f6dcedcf1ab Mon Sep 17 00:00:00 2001 From: Richard Lynch Date: Tue, 25 Jun 2024 10:46:24 +0100 Subject: [PATCH 12/66] Adds bank and building society details --- .../slug_sequence.rb | 16 +++++- .../claims/check_your_answers.html.erb | 8 +++ .../teacher_route_completing_the_form_spec.rb | 41 +++++++++++++- .../step_helpers.rb | 53 ++++++++++++++++++- 4 files changed, 114 insertions(+), 4 deletions(-) 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 0c7cc15962..3e7de92044 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 @@ -26,12 +26,23 @@ class SlugSequence "mobile-verification" ] + PAYMENT_DETAILS_SLUGS = [ + "bank-or-building-society", + "personal-bank-account", + "building-society-account" + ].freeze + RESULTS_SLUGS = [ "check-your-answers", "ineligible" ].freeze - SLUGS = ELIGIBILITY_SLUGS + PERSONAL_DETAILS_SLUGS + RESULTS_SLUGS + SLUGS = ( + ELIGIBILITY_SLUGS + + PERSONAL_DETAILS_SLUGS + + PAYMENT_DETAILS_SLUGS + + RESULTS_SLUGS + ).freeze def self.start_page_url if Rails.env.production? @@ -55,6 +66,9 @@ def slugs sequence.delete("mobile-number") sequence.delete("mobile-verification") end + + sequence.delete("personal-bank-account") if answers.building_society? + sequence.delete("building-society-account") if answers.personal_bank_account? end end end diff --git a/app/views/get_a_teacher_relocation_payment/claims/check_your_answers.html.erb b/app/views/get_a_teacher_relocation_payment/claims/check_your_answers.html.erb index 470c79b3d6..7ec5c0d37c 100644 --- a/app/views/get_a_teacher_relocation_payment/claims/check_your_answers.html.erb +++ b/app/views/get_a_teacher_relocation_payment/claims/check_your_answers.html.erb @@ -23,6 +23,14 @@ } ) %> + <%= render( + partial: "claims/check_your_answers_section", + locals: { + heading: "Payment details", + answers: journey.answers_for_claim(@form.journey_session).payment_answers + } + ) %> +

<%= t("check_your_answers.heading_send_application") %>

<%= t("check_your_answers.statement") %>

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 f863d3aaab..7e21e65888 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 @@ -45,6 +45,7 @@ and_i_complete_the_postcode_step and_i_complete_the_email_address_step and_i_dont_provide_my_mobile_number + and_i_provide_my_personal_bank_details and_the_personal_details_section_has_been_temporarily_stubbed then_the_check_your_answers_part_page_shows_my_answers and_i_submit_the_application @@ -60,6 +61,7 @@ and_i_complete_the_manual_address_step and_i_complete_the_email_address_step and_i_dont_provide_my_mobile_number + and_i_provide_my_personal_bank_details and_the_personal_details_section_has_been_temporarily_stubbed then_the_check_your_answers_part_page_shows_my_answers and_i_submit_the_application @@ -75,12 +77,32 @@ and_i_complete_the_manual_address_step and_i_complete_the_email_address_step and_i_provide_my_mobile_number + and_i_provide_my_personal_bank_details and_the_personal_details_section_has_been_temporarily_stubbed then_the_check_your_answers_part_page_shows_my_answers(mobile_number: true) and_i_submit_the_application then_the_application_is_submitted_successfully end end + + context "with a building society account" do + it "submits an application" do + and_i_complete_the_nationality_step_with(option: "Australian") + and_i_complete_the_passport_number_step_with(options: "123456789") + and_i_complete_the_personal_details_step + and_i_complete_the_manual_address_step + and_i_complete_the_email_address_step + and_i_provide_my_mobile_number + and_i_provide_my_building_society_details + and_the_personal_details_section_has_been_temporarily_stubbed + then_the_check_your_answers_part_page_shows_my_answers( + mobile_number: true, + building_society: true + ) + and_i_submit_the_application + then_the_application_is_submitted_successfully + end + end end def then_the_check_your_answers_part_one_page_shows_my_answers @@ -115,7 +137,7 @@ def then_the_check_your_answers_part_one_page_shows_my_answers ) end - def then_the_check_your_answers_part_page_shows_my_answers(mobile_number: false) + def then_the_check_your_answers_part_page_shows_my_answers(mobile_number: false, building_society: false) expect(page).to have_text( "What is your full name? Walter Seymour Skinner" ) @@ -149,5 +171,22 @@ def then_the_check_your_answers_part_page_shows_my_answers(mobile_number: false) "Would you like to provide your mobile number? No" ) end + + expect(page).to have_text("Name on bank account Walter Skinner") + + expect(page).to have_text("Bank sort code 123456") + + expect(page).to have_text("Bank account number 12345678") + + if building_society + expect(page).to have_text( + "What account do you want the money paid into? Building society" + ) + expect(page).to have_text("Building society roll number 12345678") + else + expect(page).to have_text( + "What account do you want the money paid into? Personal bank account" + ) + end end 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 5a5159daac..7f864174d4 100644 --- a/spec/support/get_a_teacher_relocation_payment/step_helpers.rb +++ b/spec/support/get_a_teacher_relocation_payment/step_helpers.rb @@ -23,8 +23,7 @@ def and_the_personal_details_section_has_been_temporarily_stubbed journey_session.answers.assign_attributes( attributes_for( :get_a_teacher_relocation_payment_answers, - :with_bank_details, - email_address: "test-irp-claim@example.com", + email_address: "test-irp-claim@example.com", # REMOVE THIS teacher_reference_number: "1234567", payroll_gender: "male" ) @@ -213,6 +212,44 @@ def and_i_provide_my_mobile_number click_button "Confirm" end + def and_i_provide_my_personal_bank_details + assert_on_bank_or_building_society_page! + + choose "Personal bank account" + + click_button("Continue") + + assert_on_personal_bank_account_page! + + fill_in("Name on your account", with: "Walter Skinner") + + fill_in("Sort code", with: "123456") + + fill_in("Account number", with: "12345678") + + click_button("Continue") + end + + def and_i_provide_my_building_society_details + assert_on_bank_or_building_society_page! + + choose "Building society" + + click_button("Continue") + + assert_on_building_society_account_page! + + fill_in "Name on your account", with: "Walter Skinner" + + fill_in("Sort code", with: "123456") + + fill_in("Account number", with: "12345678") + + fill_in("Building society roll number", with: "12345678") + + click_button("Continue") + end + def then_the_application_is_submitted_successfully assert_application_is_submitted! end @@ -281,6 +318,18 @@ def assert_on_provider_mobile_number_page! expect(page).to have_text("Would you like to provide your mobile number?") end + def assert_on_bank_or_building_society_page! + expect(page).to have_text("What account do you want the money paid into?") + end + + def assert_on_personal_bank_account_page! + expect(page).to have_text("Enter your personal bank account details") + end + + def assert_on_building_society_account_page! + expect(page).to have_text("Enter your building society details") + end + def assert_application_is_submitted! expect(page).to have_content("Claim submitted") expect(page).to have_content( From 17210101899da0138a14e124d9f3e652ee7f2ad4 Mon Sep 17 00:00:00 2001 From: Richard Lynch Date: Tue, 25 Jun 2024 10:48:43 +0100 Subject: [PATCH 13/66] Remove stubbed email We don't need to stub this as we've already done the capturing email step --- spec/support/get_a_teacher_relocation_payment/step_helpers.rb | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) 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 7f864174d4..95bbf81260 100644 --- a/spec/support/get_a_teacher_relocation_payment/step_helpers.rb +++ b/spec/support/get_a_teacher_relocation_payment/step_helpers.rb @@ -23,7 +23,6 @@ def and_the_personal_details_section_has_been_temporarily_stubbed journey_session.answers.assign_attributes( attributes_for( :get_a_teacher_relocation_payment_answers, - email_address: "test-irp-claim@example.com", # REMOVE THIS teacher_reference_number: "1234567", payroll_gender: "male" ) @@ -333,7 +332,7 @@ def assert_on_building_society_account_page! def assert_application_is_submitted! expect(page).to have_content("Claim submitted") expect(page).to have_content( - "We have sent you a confirmation email to test-irp-claim@example.com" + "We have sent you a confirmation email to seymour.skinner@springfieldelementary.edu" ) end end From 9dbe6edc336301fcb3a13c5a300ccea12abd5d73 Mon Sep 17 00:00:00 2001 From: Richard Lynch Date: Tue, 25 Jun 2024 10:54:48 +0100 Subject: [PATCH 14/66] Adds the payroll gender step --- .../slug_sequence.rb | 3 ++- .../teacher_route_completing_the_form_spec.rb | 8 ++++++++ .../step_helpers.rb | 17 +++++++++++++++-- 3 files changed, 25 insertions(+), 3 deletions(-) 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 3e7de92044..5e8cf1fcf4 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 @@ -29,7 +29,8 @@ class SlugSequence PAYMENT_DETAILS_SLUGS = [ "bank-or-building-society", "personal-bank-account", - "building-society-account" + "building-society-account", + "gender" ].freeze RESULTS_SLUGS = [ 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 7e21e65888..8f74cd842d 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 @@ -46,6 +46,7 @@ and_i_complete_the_email_address_step and_i_dont_provide_my_mobile_number and_i_provide_my_personal_bank_details + and_i_complete_the_payroll_gender_step and_the_personal_details_section_has_been_temporarily_stubbed then_the_check_your_answers_part_page_shows_my_answers and_i_submit_the_application @@ -62,6 +63,7 @@ and_i_complete_the_email_address_step and_i_dont_provide_my_mobile_number and_i_provide_my_personal_bank_details + and_i_complete_the_payroll_gender_step and_the_personal_details_section_has_been_temporarily_stubbed then_the_check_your_answers_part_page_shows_my_answers and_i_submit_the_application @@ -78,6 +80,7 @@ and_i_complete_the_email_address_step and_i_provide_my_mobile_number and_i_provide_my_personal_bank_details + and_i_complete_the_payroll_gender_step and_the_personal_details_section_has_been_temporarily_stubbed then_the_check_your_answers_part_page_shows_my_answers(mobile_number: true) and_i_submit_the_application @@ -94,6 +97,7 @@ and_i_complete_the_email_address_step and_i_provide_my_mobile_number and_i_provide_my_building_society_details + and_i_complete_the_payroll_gender_step and_the_personal_details_section_has_been_temporarily_stubbed then_the_check_your_answers_part_page_shows_my_answers( mobile_number: true, @@ -188,5 +192,9 @@ def then_the_check_your_answers_part_page_shows_my_answers(mobile_number: false, "What account do you want the money paid into? Personal bank account" ) end + + expect(page).to have_text( + "How is your gender recorded on your school’s payroll system? Male" + ) end 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 95bbf81260..5238d17d2a 100644 --- a/spec/support/get_a_teacher_relocation_payment/step_helpers.rb +++ b/spec/support/get_a_teacher_relocation_payment/step_helpers.rb @@ -23,8 +23,7 @@ def and_the_personal_details_section_has_been_temporarily_stubbed journey_session.answers.assign_attributes( attributes_for( :get_a_teacher_relocation_payment_answers, - teacher_reference_number: "1234567", - payroll_gender: "male" + teacher_reference_number: "1234567" ) ) journey_session.save! @@ -249,6 +248,14 @@ def and_i_provide_my_building_society_details click_button("Continue") end + def and_i_complete_the_payroll_gender_step + assert_on_payroll_gender_step! + + choose "Male" + + click_button("Continue") + end + def then_the_application_is_submitted_successfully assert_application_is_submitted! end @@ -329,6 +336,12 @@ def assert_on_building_society_account_page! expect(page).to have_text("Enter your building society details") end + def assert_on_payroll_gender_step! + expect(page).to have_text( + "How is your gender recorded on your school’s payroll system?" + ) + end + def assert_application_is_submitted! expect(page).to have_content("Claim submitted") expect(page).to have_content( From eb7ebc740e2038ed61e1b3fe93bdb5d220091ff7 Mon Sep 17 00:00:00 2001 From: Richard Lynch Date: Tue, 25 Jun 2024 11:06:31 +0100 Subject: [PATCH 15/66] Add teacher reference number screen We'll be removing this screen shortly but it is currently required for an end to end journey in the UI --- .../slug_sequence.rb | 3 ++- .../teacher_route_completing_the_form_spec.rb | 8 +++--- .../step_helpers.rb | 25 ++++++------------- 3 files changed, 14 insertions(+), 22 deletions(-) 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 5e8cf1fcf4..7c7c8e9068 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 @@ -30,7 +30,8 @@ class SlugSequence "bank-or-building-society", "personal-bank-account", "building-society-account", - "gender" + "gender", + "teacher-reference-number" ].freeze RESULTS_SLUGS = [ 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 8f74cd842d..ab047c414f 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 @@ -47,7 +47,7 @@ and_i_dont_provide_my_mobile_number and_i_provide_my_personal_bank_details and_i_complete_the_payroll_gender_step - and_the_personal_details_section_has_been_temporarily_stubbed + and_i_complete_the_trn_step then_the_check_your_answers_part_page_shows_my_answers and_i_submit_the_application then_the_application_is_submitted_successfully @@ -64,7 +64,7 @@ and_i_dont_provide_my_mobile_number and_i_provide_my_personal_bank_details and_i_complete_the_payroll_gender_step - and_the_personal_details_section_has_been_temporarily_stubbed + and_i_complete_the_trn_step then_the_check_your_answers_part_page_shows_my_answers and_i_submit_the_application then_the_application_is_submitted_successfully @@ -81,7 +81,7 @@ and_i_provide_my_mobile_number and_i_provide_my_personal_bank_details and_i_complete_the_payroll_gender_step - and_the_personal_details_section_has_been_temporarily_stubbed + and_i_complete_the_trn_step then_the_check_your_answers_part_page_shows_my_answers(mobile_number: true) and_i_submit_the_application then_the_application_is_submitted_successfully @@ -98,7 +98,7 @@ and_i_provide_my_mobile_number and_i_provide_my_building_society_details and_i_complete_the_payroll_gender_step - and_the_personal_details_section_has_been_temporarily_stubbed + and_i_complete_the_trn_step then_the_check_your_answers_part_page_shows_my_answers( mobile_number: true, building_society: true 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 5238d17d2a..bab9ffeb18 100644 --- a/spec/support/get_a_teacher_relocation_payment/step_helpers.rb +++ b/spec/support/get_a_teacher_relocation_payment/step_helpers.rb @@ -12,23 +12,6 @@ def and_i_submit_the_application click_button("Confirm and send") end - # FIXME RL make sure to remove this step it's just a temporary hack until - # we've added the personal details pages. Really don't want to modify the db - # in a feature spec! - # Also we're only temporarily adding the teacher reference number, and - # payroll gender to get the test to pass as we're not asking for it on the - # IRP journey. - def and_the_personal_details_section_has_been_temporarily_stubbed - journey_session = Journeys::GetATeacherRelocationPayment::Session.last - journey_session.answers.assign_attributes( - attributes_for( - :get_a_teacher_relocation_payment_answers, - teacher_reference_number: "1234567" - ) - ) - journey_session.save! - end - def and_i_complete_application_route_question_with(option:) choose(option) @@ -256,6 +239,14 @@ def and_i_complete_the_payroll_gender_step click_button("Continue") end + # FIXME RL: Once https://dfedigital.atlassian.net.mcas.ms/browse/CAPT-1625 + # remove this step. We don't want to capture a TRN on the IRP journey. + def and_i_complete_the_trn_step + fill_in("What is your teacher reference number (TRN)?", with: "1234567") + + click_button("Continue") + end + def then_the_application_is_submitted_successfully assert_application_is_submitted! end From c6acd0a9ca254845b69302cdbc441f2325cba671 Mon Sep 17 00:00:00 2001 From: Kenneth Lee Date: Thu, 20 Jun 2024 15:51:11 +0100 Subject: [PATCH 16/66] CAPT-1625 Move teacher_reference_number from claim to eligibility --- app/forms/teacher_reference_number_form.rb | 8 +- app/helpers/admin/claims_helper.rb | 27 ++++-- app/jobs/claim_verifier_job.rb | 2 +- app/jobs/qualifications_no_match_check_job.rb | 2 +- .../claim_verifiers/census_subjects_taught.rb | 2 +- .../claim_verifiers/employment.rb | 2 +- .../claim_verifiers/identity.rb | 4 +- app/models/claim.rb | 22 +---- .../claim/claims_preventing_payment_finder.rb | 12 ++- app/models/claim/data_report_request.rb | 2 +- app/models/claim/matching_attribute_finder.rb | 63 ++++++++++++-- app/models/claim/search.rb | 25 +++++- .../teacher_reference_number_validation.rb | 28 ++++++ app/models/concerns/trn_validation.rb | 13 --- app/models/journeys/page_sequence.rb | 10 ++- app/models/payment.rb | 25 ++++-- app/models/payroll_run.rb | 6 +- app/models/policies.rb | 2 +- .../early_career_payments/eligibility.rb | 9 +- .../eligibility.rb | 8 +- .../policies/student_loans/eligibility.rb | 8 +- .../school_workforce_census_data_importer.rb | 10 +-- app/models/topup.rb | 6 +- app/views/admin/amendments/new.html.erb | 24 ++--- app/views/admin/tasks/_claim_summary.html.erb | 2 +- config/analytics.yml | 3 + config/brakeman.ignore | 56 ++---------- ...teacher_reference_number_to_eligibility.rb | 19 ++++ db/schema.rb | 8 +- spec/factories/amendments.rb | 4 +- spec/factories/claims.rb | 1 - .../early_career_payments/eligibilities.rb | 1 + .../eligibilities.rb | 3 +- spec/factories/payments.rb | 4 +- spec/factories/student_loans/eligibilities.rb | 1 + spec/features/admin_amend_claim_spec.rb | 6 +- ...in_claim_tasks_update_with_dqt_api_spec.rb | 38 ++++---- ...h_inconsistent_payroll_information_spec.rb | 2 +- .../admin_claim_with_matching_details_spec.rb | 2 +- .../admin_data_report_request_spec.rb | 2 +- spec/features/admin_search_spec.rb | 4 +- .../early_career_payments_claim_spec.rb | 6 +- .../levelling_up_premium_payments_spec.rb | 2 +- spec/helpers/admin/claims_helper_spec.rb | 14 +-- .../qualifications_no_match_check_job_spec.rb | 2 +- spec/mailers/payment_mailer_spec.rb | 7 +- spec/models/amendment_spec.rb | 87 ++++++++++++------- .../census_subjects_taught_spec.rb | 28 +++--- .../claim_verifiers/employment_spec.rb | 4 +- .../claim_verifiers/identity_spec.rb | 16 ++-- .../claim_verifiers/induction_spec.rb | 4 +- .../claim_verifiers/qualifications_spec.rb | 10 +-- .../claims_preventing_payment_finder_spec.rb | 8 +- spec/models/claim/data_report_request_spec.rb | 4 +- .../claim/matching_attribute_finder_spec.rb | 24 ++--- .../claim/personal_data_scrubber_spec.rb | 2 +- spec/models/claim/search_spec.rb | 4 +- spec/models/claim_auto_approval_spec.rb | 2 +- spec/models/claim_checking_tasks_spec.rb | 4 +- spec/models/claim_spec.rb | 20 ++--- spec/models/decision_spec.rb | 2 +- .../early_career_payments/eligibility_spec.rb | 6 +- spec/models/payment_spec.rb | 12 +-- spec/models/payroll/payment_csv_row_spec.rb | 6 +- spec/models/payroll_run_spec.rb | 24 ++--- spec/models/policies_spec.rb | 4 +- spec/models/student_loans/eligibility_spec.rb | 4 +- spec/models/teachers_pensions_service_spec.rb | 4 +- spec/requests/admin_amendments_spec.rb | 22 ++--- spec/requests/admin_claims_spec.rb | 2 +- spec/requests/admin_decisions_spec.rb | 2 +- spec/requests/admin_payroll_runs_spec.rb | 6 +- spec/requests/admin_tps_data_upload_spec.rb | 18 ++-- ...dmin_edit_claim_feature_shared_examples.rb | 2 +- ...dmin_view_claim_feature_shared_examples.rb | 5 +- spec/support/fixture_helpers.rb | 16 ++-- 76 files changed, 503 insertions(+), 356 deletions(-) create mode 100644 app/models/concerns/teacher_reference_number_validation.rb delete mode 100644 app/models/concerns/trn_validation.rb create mode 100644 db/migrate/20240511100914_move_teacher_reference_number_to_eligibility.rb diff --git a/app/forms/teacher_reference_number_form.rb b/app/forms/teacher_reference_number_form.rb index 28c817853b..9a37d30e71 100644 --- a/app/forms/teacher_reference_number_form.rb +++ b/app/forms/teacher_reference_number_form.rb @@ -1,9 +1,9 @@ class TeacherReferenceNumberForm < Form + include TeacherReferenceNumberValidation + attribute :teacher_reference_number - before_validation do - self.teacher_reference_number = teacher_reference_number&.gsub(/\D/, "") - end + before_validation :normalise_teacher_reference_number validates :teacher_reference_number, presence: { @@ -12,7 +12,7 @@ class TeacherReferenceNumberForm < Form validates :teacher_reference_number, length: { - is: 7, + is: TRN_LENGTH, message: ->(form, _) { form.i18n_errors_path("length") } }, if: -> { teacher_reference_number.present? } diff --git a/app/helpers/admin/claims_helper.rb b/app/helpers/admin/claims_helper.rb index 5eb9a7c079..fc6cefde5c 100644 --- a/app/helpers/admin/claims_helper.rb +++ b/app/helpers/admin/claims_helper.rb @@ -36,7 +36,7 @@ def personal_data_removed_text def admin_personal_details(claim) [ - [translate("admin.teacher_reference_number"), claim.teacher_reference_number], + [translate("admin.teacher_reference_number"), claim.eligibility.teacher_reference_number], [translate("govuk_verify_fields.full_name").capitalize, claim.personal_data_removed? ? personal_data_removed_text : claim.full_name], [translate("govuk_verify_fields.date_of_birth").capitalize, claim.personal_data_removed? ? personal_data_removed_text : l(claim.date_of_birth, format: :day_month_year)], [translate("admin.national_insurance_number"), claim.personal_data_removed? ? personal_data_removed_text : claim.national_insurance_number], @@ -98,11 +98,19 @@ def claim_route(claim) end def matching_attributes(first_claim, second_claim) - first_attributes = matching_attributes_for(first_claim) - second_attributes = matching_attributes_for(second_claim) + first_attributes = matching_attributes_for_claim(first_claim) + second_attributes = matching_attributes_for_claim(second_claim) + + first_eligibility_attributes = matching_attributes_for_eligibility(first_claim.eligibility) + second_eligibility_attributes = matching_attributes_for_eligibility(second_claim.eligibility) matching_attributes = first_attributes & second_attributes - matching_attributes.to_h.compact.keys.map(&:humanize).sort + claim_matches = matching_attributes.to_h.compact.keys.map(&:humanize).sort + + matching_eligibility_attributes = first_eligibility_attributes & second_eligibility_attributes + eligibility_matches = matching_eligibility_attributes.to_h.compact.keys.map(&:humanize).sort + + claim_matches + eligibility_matches end def identity_confirmation_task_claim_verifier_match_status_tag(claim) @@ -226,9 +234,16 @@ def no_claims(status) private - def matching_attributes_for(claim) + def matching_attributes_for_claim(claim) claim.attributes - .slice(*Claim::MatchingAttributeFinder::ATTRIBUTE_GROUPS_TO_MATCH.flatten) + .slice(*Claim::MatchingAttributeFinder::CLAIM_ATTRIBUTE_GROUPS_TO_MATCH.flatten) + .reject { |_, v| v.blank? } + .to_a + end + + def matching_attributes_for_eligibility(eligibility) + eligibility.attributes + .slice(*Claim::MatchingAttributeFinder::ELIGIBILITY_ATTRIBUTE_GROUPS_TO_MATCH[eligibility.policy].flatten) .reject { |_, v| v.blank? } .to_a end diff --git a/app/jobs/claim_verifier_job.rb b/app/jobs/claim_verifier_job.rb index 70ab84cf64..d876bbfbfa 100644 --- a/app/jobs/claim_verifier_job.rb +++ b/app/jobs/claim_verifier_job.rb @@ -3,7 +3,7 @@ def perform(claim) AutomatedChecks::ClaimVerifier.new( claim:, dqt_teacher_status: claim.has_dqt_record? ? Dqt::Teacher.new(claim.dqt_teacher_status) : Dqt::Client.new.teacher.find( - claim.teacher_reference_number, + claim.eligibility.teacher_reference_number, birthdate: claim.date_of_birth.to_s, nino: claim.national_insurance_number ) diff --git a/app/jobs/qualifications_no_match_check_job.rb b/app/jobs/qualifications_no_match_check_job.rb index b953316190..832100e5e3 100644 --- a/app/jobs/qualifications_no_match_check_job.rb +++ b/app/jobs/qualifications_no_match_check_job.rb @@ -24,7 +24,7 @@ def perform(filter: nil) AutomatedChecks::ClaimVerifiers::Qualifications.new( claim: claim, dqt_teacher_status: Dqt::Client.new.teacher.find( - claim.teacher_reference_number, + claim.eligibility.teacher_reference_number, birthdate: claim.date_of_birth.to_s, nino: claim.national_insurance_number ) diff --git a/app/models/automated_checks/claim_verifiers/census_subjects_taught.rb b/app/models/automated_checks/claim_verifiers/census_subjects_taught.rb index a520bf35d2..6bb0f26cc7 100644 --- a/app/models/automated_checks/claim_verifiers/census_subjects_taught.rb +++ b/app/models/automated_checks/claim_verifiers/census_subjects_taught.rb @@ -10,7 +10,7 @@ def initialize( ) self.admin_user = admin_user self.claim = claim - self.school_workforce_census = SchoolWorkforceCensus.where(teacher_reference_number: claim.teacher_reference_number) + self.school_workforce_census = SchoolWorkforceCensus.where(teacher_reference_number: claim.eligibility.teacher_reference_number) self.school_workforce_census_subjects = school_workforce_census end diff --git a/app/models/automated_checks/claim_verifiers/employment.rb b/app/models/automated_checks/claim_verifiers/employment.rb index fe376ae4c8..d3186ef15c 100644 --- a/app/models/automated_checks/claim_verifiers/employment.rb +++ b/app/models/automated_checks/claim_verifiers/employment.rb @@ -7,7 +7,7 @@ class Employment def initialize(claim:, admin_user: nil) self.admin_user = admin_user self.claim = claim - self.teachers_pensions_service = TeachersPensionsService.by_teacher_reference_number(claim.teacher_reference_number) + self.teachers_pensions_service = TeachersPensionsService.by_teacher_reference_number(claim.eligibility.teacher_reference_number) end def perform diff --git a/app/models/automated_checks/claim_verifiers/identity.rb b/app/models/automated_checks/claim_verifiers/identity.rb index d6ad1ef1c9..c6d31d8cc3 100644 --- a/app/models/automated_checks/claim_verifiers/identity.rb +++ b/app/models/automated_checks/claim_verifiers/identity.rb @@ -147,7 +147,7 @@ def partial_match unless trn_matched? notes << create_field_note( name: "Teacher reference number", - claimant: claim.teacher_reference_number, + claimant: claim.eligibility.teacher_reference_number, dqt: dqt_teacher_status.teacher_reference_number ) end @@ -162,7 +162,7 @@ def tasks=(tasks) end def trn_matched? - claim.teacher_reference_number == dqt_teacher_status.teacher_reference_number + claim.eligibility.teacher_reference_number == dqt_teacher_status.teacher_reference_number end end end diff --git a/app/models/claim.rb b/app/models/claim.rb index 818faae867..625b7b2f22 100644 --- a/app/models/claim.rb +++ b/app/models/claim.rb @@ -2,12 +2,10 @@ class Claim < ApplicationRecord MIN_QA_THRESHOLD = 10 - TRN_LENGTH = 7 NO_STUDENT_LOAN = "not_applicable" STUDENT_LOAN_PLAN_OPTIONS = StudentLoan::PLANS.dup << NO_STUDENT_LOAN ADDRESS_ATTRIBUTES = %w[address_line_1 address_line_2 address_line_3 address_line_4 postcode].freeze AMENDABLE_ATTRIBUTES = %i[ - teacher_reference_number national_insurance_number date_of_birth student_loan_plan @@ -22,7 +20,6 @@ class Claim < ApplicationRecord address_line_4: true, postcode: true, payroll_gender: true, - teacher_reference_number: true, national_insurance_number: true, has_student_loan: false, student_loan_country: false, @@ -76,7 +73,8 @@ class Claim < ApplicationRecord qualifications_details_check: true, dqt_teacher_status: false, submitted_using_slc_data: false, - journeys_session_id: false + journeys_session_id: false, + column_to_remove_teacher_reference_number: true }.freeze DECISION_DEADLINE = 12.weeks DECISION_DEADLINE_WARNING_POINT = 2.weeks @@ -126,9 +124,6 @@ class Claim < ApplicationRecord validates :academic_year_before_type_cast, format: {with: AcademicYear::ACADEMIC_YEAR_REGEXP} - validates :teacher_reference_number, on: [:submit, :amendment], presence: {message: "Enter your teacher reference number"} - validate :trn_must_be_seven_digits - validates :has_student_loan, on: [:"student-loan"], inclusion: {in: [true, false]} validates :student_loan_plan, inclusion: {in: STUDENT_LOAN_PLAN_OPTIONS}, allow_nil: true validates :student_loan_plan, on: [:"student-loan", :amendment], presence: {message: "Enter a valid student loan plan"} @@ -147,7 +142,6 @@ class Claim < ApplicationRecord validate :building_society_roll_number_must_be_between_one_and_eighteen_digits validate :building_society_roll_number_must_be_in_a_valid_format - before_save :normalise_trn, if: :teacher_reference_number_changed? before_save :normalise_ni_number, if: :national_insurance_number_changed? before_save :normalise_bank_account_number, if: :bank_account_number_changed? before_save :normalise_bank_sort_code, if: :bank_sort_code_changed? @@ -405,18 +399,6 @@ def set_a_reminder? private - def normalise_trn - self.teacher_reference_number = normalised_trn - end - - def normalised_trn - teacher_reference_number.gsub(/\D/, "") - end - - def trn_must_be_seven_digits - errors.add(:teacher_reference_number, "Teacher reference number must be 7 digits") if teacher_reference_number.present? && normalised_trn.length != TRN_LENGTH - end - def normalise_ni_number self.national_insurance_number = normalised_ni_number end diff --git a/app/models/claim/claims_preventing_payment_finder.rb b/app/models/claim/claims_preventing_payment_finder.rb index 3526a56fe2..7646b94074 100644 --- a/app/models/claim/claims_preventing_payment_finder.rb +++ b/app/models/claim/claims_preventing_payment_finder.rb @@ -22,14 +22,20 @@ def claims_preventing_payment private def find_claims_preventing_payment - payrollable_claims_from_same_claimant = Claim.payrollable.where(teacher_reference_number: claim.teacher_reference_number) + eligibility_ids = [ + Policies::StudentLoans::Eligibility.where(teacher_reference_number: claim.eligibility.teacher_reference_number), + Policies::EarlyCareerPayments::Eligibility.where(teacher_reference_number: claim.eligibility.teacher_reference_number), + Policies::LevellingUpPremiumPayments::Eligibility.where(teacher_reference_number: claim.eligibility.teacher_reference_number) + ].flatten.map(&:id) + + payrollable_claims_from_same_claimant = Claim.payrollable.where(eligibility_id: eligibility_ids) payrollable_topup_claims_from_same_claimant = Topup.includes(:claim).payrollable - .select { |t| t.claim.teacher_reference_number == claim.teacher_reference_number } + .select { |t| t.claim.eligibility.teacher_reference_number == claim.eligibility.teacher_reference_number } .map(&:claim) [payrollable_claims_from_same_claimant, payrollable_topup_claims_from_same_claimant].reduce([], :concat).select do |other_claim| - Payment::PERSONAL_DETAILS_ATTRIBUTES_FORBIDDING_DISCREPANCIES.any? do |attribute| + Payment::PERSONAL_CLAIM_DETAILS_ATTRIBUTES_FORBIDDING_DISCREPANCIES.any? do |attribute| attribute_does_not_match?(other_claim, attribute) end end diff --git a/app/models/claim/data_report_request.rb b/app/models/claim/data_report_request.rb index f07637dd51..2d7d423433 100644 --- a/app/models/claim/data_report_request.rb +++ b/app/models/claim/data_report_request.rb @@ -28,7 +28,7 @@ def to_csv @claims.each do |claim| csv << [ ExcelUtils.escape_formulas(claim.reference), - ExcelUtils.escape_formulas(claim.teacher_reference_number), + ExcelUtils.escape_formulas(claim.eligibility.teacher_reference_number), ExcelUtils.escape_formulas(claim.national_insurance_number), ExcelUtils.escape_formulas(claim.full_name), ExcelUtils.escape_formulas(claim.email_address), diff --git a/app/models/claim/matching_attribute_finder.rb b/app/models/claim/matching_attribute_finder.rb index 74825e3925..dbf4f650b9 100644 --- a/app/models/claim/matching_attribute_finder.rb +++ b/app/models/claim/matching_attribute_finder.rb @@ -1,29 +1,52 @@ class Claim class MatchingAttributeFinder - ATTRIBUTE_GROUPS_TO_MATCH = [ - ["teacher_reference_number"], + STUDENT_LOANS_AND_ADDITIONAL_PAYMENTS_GROUP = [ + Policies::StudentLoans, + Policies::EarlyCareerPayments, + Policies::LevellingUpPremiumPayments + ] + + # From the source_claim use this determine which group to use for comparison + CROSS_POLICY_MATCH_GROUPS = { + Policies::StudentLoans => STUDENT_LOANS_AND_ADDITIONAL_PAYMENTS_GROUP, + Policies::EarlyCareerPayments => STUDENT_LOANS_AND_ADDITIONAL_PAYMENTS_GROUP, + Policies::LevellingUpPremiumPayments => STUDENT_LOANS_AND_ADDITIONAL_PAYMENTS_GROUP + } + + # Fields on the claim model to consider a match + CLAIM_ATTRIBUTE_GROUPS_TO_MATCH = [ ["email_address"], ["national_insurance_number"], ["bank_account_number", "bank_sort_code", "building_society_roll_number"] ].freeze + # Fields on the eligibility that are considered a match + ELIGIBILITY_ATTRIBUTE_GROUPS_TO_MATCH = { + Policies::StudentLoans => [["teacher_reference_number"]], + Policies::EarlyCareerPayments => [["teacher_reference_number"]], + Policies::LevellingUpPremiumPayments => [["teacher_reference_number"]] + } + def initialize(source_claim) @source_claim = source_claim end # Returns a list of claims that could potentially be from the same applicant # because they either share a same single attribute with the source claim, - # (for example, the same TRN, or email), or they share a group of attributes + # (for example, the same national_insurance_number, email, etc...), or they share a group of attributes # with the source claim (for example bank sort code, account number and roll # number). # + # The associated eligibility fields can be used as well + # # This may not necessarily mean the claim cannot be approved, but means it # warrants a degree of caution and further investigation. def matching_claims match_queries = Claim.none - ATTRIBUTE_GROUPS_TO_MATCH.each do |attributes| - vals = values_for_attributes(attributes) + # Claim attributes + CLAIM_ATTRIBUTE_GROUPS_TO_MATCH.each do |attributes| + vals = values_for_attributes(@source_claim, attributes) next if vals.blank? @@ -33,20 +56,46 @@ def matching_claims match_queries = match_queries.or(query) end + # Eligibility attributes + eligibility_ids = eligibility_attributes_groups_to_match.map { |attributes| + vals = values_for_attributes(@source_claim.eligibility, attributes) + concatenated_columns = "CONCAT(#{attributes.join(",")})" + + policies_to_find_matches.map { |policy| + policy::Eligibility.where("LOWER(#{concatenated_columns}) = LOWER(?)", vals.join) + } + }.flatten.map(&:id) + + eligibility_match_query = Claim.where(eligibility_id: eligibility_ids) + match_queries = match_queries.or(eligibility_match_query) + claims_to_compare.merge(match_queries) end private + def policies_to_find_matches + CROSS_POLICY_MATCH_GROUPS[@source_claim.policy] + end + + def eligibility_attributes_groups_to_match + ELIGIBILITY_ATTRIBUTE_GROUPS_TO_MATCH[@source_claim.policy] + end + + def policies_to_find_matches_eligibility_types + policies_to_find_matches.map { |policy| policy::Eligibility.to_s } + end + def claims_to_compare Claim.submitted .by_academic_year(@source_claim.academic_year) + .by_policies(policies_to_find_matches) .where.not(id: @source_claim.id) end - def values_for_attributes(attributes) + def values_for_attributes(object, attributes) attributes.map { |attribute| - @source_claim.read_attribute(attribute) + object.read_attribute(attribute) }.reject(&:blank?) end end diff --git a/app/models/claim/search.rb b/app/models/claim/search.rb index 30045149f5..2766df5b3c 100644 --- a/app/models/claim/search.rb +++ b/app/models/claim/search.rb @@ -1,14 +1,23 @@ class Claim # Accepts a search term and returns all Claims that match against any of the - # attributes defined in the `SEARCHABLE_ATTRIBUTES` constant. Both subject + # attributes defined in the `SEARCHABLE_ATTRIBUTES` or `SEARCHABLE_ELIGIBILITY_ATTRIBUTES` constant. Both subject # and attribute are downcased, so the search is case-insensitive. class Search attr_accessor :search_term - SEARCHABLE_ATTRIBUTES = %w[ + POLICIES = [ + Policies::StudentLoans, + Policies::EarlyCareerPayments, + Policies::LevellingUpPremiumPayments + ] + + SEARCHABLE_CLAIM_ATTRIBUTES = %w[ reference email_address surname + ] + + SEARCHABLE_ELIGIBILITY_ATTRIBUTES = %w[ teacher_reference_number ] @@ -17,9 +26,17 @@ def initialize(search_term) end def claims - SEARCHABLE_ATTRIBUTES.inject(Claim.none) do |relation, attribute| + claim_match_query = SEARCHABLE_CLAIM_ATTRIBUTES.inject(Claim.none) { |relation, attribute| relation.or(search_by(attribute)) - end + } + + eligibility_ids = SEARCHABLE_ELIGIBILITY_ATTRIBUTES.map { |attribute| + POLICIES.map { |policy| + policy::Eligibility.where("LOWER(#{attribute}) = LOWER(?)", search_term) + } + }.flatten.map(&:id) + + claim_match_query.or(Claim.where(eligibility_id: eligibility_ids)) end private diff --git a/app/models/concerns/teacher_reference_number_validation.rb b/app/models/concerns/teacher_reference_number_validation.rb new file mode 100644 index 0000000000..84d49c1637 --- /dev/null +++ b/app/models/concerns/teacher_reference_number_validation.rb @@ -0,0 +1,28 @@ +module TeacherReferenceNumberValidation + extend ActiveSupport::Concern + + TRN_LENGTH = 7 + + def validate_teacher_reference_number_length + if teacher_reference_number.present? && !valid_teacher_reference_number_length?(teacher_reference_number) + errors.add(:teacher_reference_number, "Teacher reference number must be #{TRN_LENGTH} digits") + end + end + + def normalise_teacher_reference_number + self.teacher_reference_number = normalised_teacher_reference_number(teacher_reference_number) + end + + def normalised_teacher_reference_number(trn) + trn.to_s.gsub(/\D/, "") + end + + def valid_teacher_reference_number_length?(trn) + trn.to_s.length == TRN_LENGTH + end + + # For some reason less than 7 digits is a thing for the school workforce census import! + def valid_teacher_reference_number_length_for_school_workforce_census?(trn) + trn.to_s.length <= TRN_LENGTH + end +end diff --git a/app/models/concerns/trn_validation.rb b/app/models/concerns/trn_validation.rb deleted file mode 100644 index 8ae027c4dc..0000000000 --- a/app/models/concerns/trn_validation.rb +++ /dev/null @@ -1,13 +0,0 @@ -module TrnValidation - extend ActiveSupport::Concern - - TRN_LENGTH = 7 - - def normalize_teacher_reference_number(teacher_reference_number) - teacher_reference_number.to_s.gsub(/\D/, "") - end - - def valid_trn_length?(teacher_reference_number) - teacher_reference_number.length <= TRN_LENGTH - end -end diff --git a/app/models/journeys/page_sequence.rb b/app/models/journeys/page_sequence.rb index d6fe3bcead..9997705587 100644 --- a/app/models/journeys/page_sequence.rb +++ b/app/models/journeys/page_sequence.rb @@ -26,7 +26,7 @@ def next_slug return "ineligible" if journey_ineligible? - if claim_submittable? + if completed? return "student-loan-amount" if updating_personal_details? && in_sequence?("student-loan-amount") return "check-your-answers" end @@ -119,5 +119,13 @@ def claim_submittable? def journey_ineligible? @journey_ineligible ||= journey::EligibilityChecker.new(journey_session: @journey_session).ineligible? end + + def completed? + if journey == Journeys::AdditionalPaymentsForTeaching + claim_submittable? && answers.teacher_reference_number.present? + else + claim_submittable? + end + end end end diff --git a/app/models/payment.rb b/app/models/payment.rb index 843546e8e6..e9fdf3027c 100644 --- a/app/models/payment.rb +++ b/app/models/payment.rb @@ -16,7 +16,7 @@ class Payment < ApplicationRecord validates :scheduled_payment_date, presence: true, on: :upload validate :personal_details_must_be_consistent - PERSONAL_DETAILS_ATTRIBUTES_PERMITTING_DISCREPANCIES = %i[ + PERSONAL_CLAIM_DETAILS_ATTRIBUTES_PERMITTING_DISCREPANCIES = %i[ first_name middle_name surname @@ -31,8 +31,7 @@ class Payment < ApplicationRecord banking_name national_insurance_number ] - PERSONAL_DETAILS_ATTRIBUTES_FORBIDDING_DISCREPANCIES = %i[ - teacher_reference_number + PERSONAL_CLAIM_DETAILS_ATTRIBUTES_FORBIDDING_DISCREPANCIES = %i[ date_of_birth student_loan_plan bank_sort_code @@ -40,7 +39,11 @@ class Payment < ApplicationRecord building_society_roll_number ] - delegate(*(PERSONAL_DETAILS_ATTRIBUTES_PERMITTING_DISCREPANCIES + PERSONAL_DETAILS_ATTRIBUTES_FORBIDDING_DISCREPANCIES), to: :claim_for_personal_details) + PERSONAL_ELIGIBILITY_DETAILS_ATTRIBUTES_FORBIDDING_DISCREPANCIES = %i[ + teacher_reference_number + ] + + delegate(*(PERSONAL_CLAIM_DETAILS_ATTRIBUTES_PERMITTING_DISCREPANCIES + PERSONAL_CLAIM_DETAILS_ATTRIBUTES_FORBIDDING_DISCREPANCIES), to: :claim_for_personal_details) def policies_in_payment claims.map { |claim| claim.policy.payroll_file_name }.uniq.sort.join(" ") @@ -53,14 +56,22 @@ def confirmed? private def personal_details_must_be_consistent - mismatching_attributes = PERSONAL_DETAILS_ATTRIBUTES_FORBIDDING_DISCREPANCIES.select { |attribute| + mismatching_attributes = PERSONAL_CLAIM_DETAILS_ATTRIBUTES_FORBIDDING_DISCREPANCIES.select { |attribute| attribute_values = claims.map(&attribute) attribute_values.uniq.count > 1 && !attribute_values.all?(&:blank?) } - if mismatching_attributes.any? + mismatching_eligibility_attributes = PERSONAL_ELIGIBILITY_DETAILS_ATTRIBUTES_FORBIDDING_DISCREPANCIES.select { |attribute| + attribute_values = claims.map(&:eligibility).map(&attribute) + attribute_values.uniq.count > 1 && !attribute_values.all?(&:blank?) + } + + if mismatching_attributes.any? || mismatching_eligibility_attributes.any? claims_sentence = claims.map(&:reference).to_sentence - attributes_sentence = mismatching_attributes.map { |attribute| Claim.human_attribute_name(attribute).downcase }.to_sentence + attributes_list = mismatching_attributes.map { |attribute| Claim.human_attribute_name(attribute).downcase } + attributes_list += mismatching_eligibility_attributes.map { |attribute| claims.first.eligibility.class.human_attribute_name(attribute).downcase } + attributes_sentence = attributes_list.to_sentence + errors.add(:claims, "#{claims_sentence} have different values for #{attributes_sentence}") end end diff --git a/app/models/payroll_run.rb b/app/models/payroll_run.rb index ec658a4ce2..e40b085a05 100644 --- a/app/models/payroll_run.rb +++ b/app/models/payroll_run.rb @@ -48,7 +48,7 @@ def all_payments_confirmed? def self.create_with_claims!(claims, topups, attrs = {}) ActiveRecord::Base.transaction do PayrollRun.create!(attrs).tap do |payroll_run| - [claims, topups].reduce([], :concat).group_by(&:teacher_reference_number).each_value do |grouped_items| + [claims, topups].reduce([], :concat).group_by { |obj| group_by_field(obj) }.each_value do |grouped_items| # associates the claim to the payment, for Topup that's its associated claim grouped_claims = grouped_items.map { |i| i.is_a?(Topup) ? i.claim : i } @@ -62,6 +62,10 @@ def self.create_with_claims!(claims, topups, attrs = {}) end end + def self.group_by_field(obj) + obj.is_a?(Claim) ? obj.eligibility.teacher_reference_number : obj.teacher_reference_number + end + def download_triggered? downloaded_at.present? && downloaded_by.present? end diff --git a/app/models/policies.rb b/app/models/policies.rb index 9929012d76..c155fd43bf 100644 --- a/app/models/policies.rb +++ b/app/models/policies.rb @@ -7,7 +7,7 @@ module Policies AMENDABLE_ELIGIBILITY_ATTRIBUTES = POLICIES.map do |policy| policy::Eligibility::AMENDABLE_ATTRIBUTES - end.flatten.freeze + end.flatten.uniq.freeze def self.all POLICIES diff --git a/app/models/policies/early_career_payments/eligibility.rb b/app/models/policies/early_career_payments/eligibility.rb index 0d54f9cdcd..b01583141e 100644 --- a/app/models/policies/early_career_payments/eligibility.rb +++ b/app/models/policies/early_career_payments/eligibility.rb @@ -1,11 +1,13 @@ module Policies module EarlyCareerPayments class Eligibility < ApplicationRecord + include TeacherReferenceNumberValidation + def policy Policies::EarlyCareerPayments end - AMENDABLE_ATTRIBUTES = [:award_amount].freeze + AMENDABLE_ATTRIBUTES = [:teacher_reference_number, :award_amount].freeze IGNORED_ATTRIBUTES = [ "eligible_degree_subject" @@ -58,10 +60,15 @@ def self.max_award_amount_in_pounds has_one :claim, as: :eligibility, inverse_of: :eligibility belongs_to :current_school, optional: true, class_name: "School" + before_validation :normalise_teacher_reference_number, if: :teacher_reference_number_changed? + validates :current_school, on: [:"correct-school"], presence: {message: "Select the school you teach at or choose somewhere else"}, unless: :school_somewhere_else? validates_numericality_of :award_amount, message: "Enter a valid monetary amount", allow_nil: true, greater_than_or_equal_to: 0, less_than_or_equal_to: 7500 validates :award_amount, on: :amendment, award_range: {max: max_award_amount_in_pounds} + validates :teacher_reference_number, on: :amendment, presence: {message: "Enter your teacher reference number"} + validate :validate_teacher_reference_number_length + delegate :name, to: :current_school, prefix: true, allow_nil: true delegate :academic_year, to: :claim diff --git a/app/models/policies/levelling_up_premium_payments/eligibility.rb b/app/models/policies/levelling_up_premium_payments/eligibility.rb index 65b3542219..042b95ba67 100644 --- a/app/models/policies/levelling_up_premium_payments/eligibility.rb +++ b/app/models/policies/levelling_up_premium_payments/eligibility.rb @@ -1,6 +1,8 @@ module Policies module LevellingUpPremiumPayments class Eligibility < ApplicationRecord + include TeacherReferenceNumberValidation + def policy Policies::LevellingUpPremiumPayments end @@ -11,11 +13,15 @@ def policy has_one :claim, as: :eligibility, inverse_of: :eligibility belongs_to :current_school, optional: true, class_name: "School" + before_validation :normalise_teacher_reference_number, if: :teacher_reference_number_changed? + validate :award_amount_must_be_in_range, on: :amendment + validates :teacher_reference_number, on: :amendment, presence: {message: "Enter your teacher reference number"} + validate :validate_teacher_reference_number_length delegate :name, to: :current_school, prefix: true, allow_nil: true - AMENDABLE_ATTRIBUTES = [:award_amount].freeze + AMENDABLE_ATTRIBUTES = [:teacher_reference_number, :award_amount].freeze FIRST_ITT_AY = "2017/2018" LAST_POLICY_YEAR = "2024/2025" diff --git a/app/models/policies/student_loans/eligibility.rb b/app/models/policies/student_loans/eligibility.rb index 4d701cb2e5..7b366caef3 100644 --- a/app/models/policies/student_loans/eligibility.rb +++ b/app/models/policies/student_loans/eligibility.rb @@ -3,6 +3,8 @@ module Policies module StudentLoans class Eligibility < ApplicationRecord + include TeacherReferenceNumberValidation + SUBJECT_ATTRIBUTES = [ :biology_taught, :chemistry_taught, @@ -10,7 +12,7 @@ class Eligibility < ApplicationRecord :computing_taught, :languages_taught ].freeze - AMENDABLE_ATTRIBUTES = %i[student_loan_repayment_amount].freeze + AMENDABLE_ATTRIBUTES = %i[teacher_reference_number student_loan_repayment_amount].freeze self.table_name = "student_loans_eligibilities" @@ -34,12 +36,16 @@ class Eligibility < ApplicationRecord belongs_to :claim_school, optional: true, class_name: "School" belongs_to :current_school, optional: true, class_name: "School" + before_validation :normalise_teacher_reference_number, if: :teacher_reference_number_changed? + validates :claim_school, on: [:"select-claim-school"], presence: {message: ->(object, _data) { object.select_claim_school_presence_error_message }}, unless: :claim_school_somewhere_else? validates :employment_status, on: [:submit], presence: {message: ->(object, _data) { "Select if you still work at #{object.claim_school_name}, another school or no longer teach in England" }} validates :had_leadership_position, on: [:submit], inclusion: {in: [true, false], message: "Select yes if you were employed in a leadership position"} validates :mostly_performed_leadership_duties, on: [:submit], inclusion: {in: [true, false], message: "Select yes if you spent more than half your working hours on leadership duties"}, if: :had_leadership_position? validates_numericality_of :student_loan_repayment_amount, message: "Enter a valid monetary amount", allow_nil: true, greater_than_or_equal_to: 0, less_than_or_equal_to: 99999 validates :student_loan_repayment_amount, on: :amendment, award_range: {max: 5_000} + validates :teacher_reference_number, on: :amendment, presence: {message: "Enter your teacher reference number"} + validate :validate_teacher_reference_number_length delegate :name, to: :claim_school, prefix: true, allow_nil: true delegate :name, to: :current_school, prefix: true, allow_nil: true diff --git a/app/models/school_workforce_census_data_importer.rb b/app/models/school_workforce_census_data_importer.rb index 528db56cd1..b414893d2c 100644 --- a/app/models/school_workforce_census_data_importer.rb +++ b/app/models/school_workforce_census_data_importer.rb @@ -1,5 +1,5 @@ class SchoolWorkforceCensusDataImporter < CsvImporter::Base - include ::TrnValidation + include ::TeacherReferenceNumberValidation import_options( target_data_model: SchoolWorkforceCensus, @@ -11,12 +11,12 @@ class SchoolWorkforceCensusDataImporter < CsvImporter::Base private def skip_row_conditions?(row) - row[0].blank? || row[4] == "NULL" || row[0] == "NULL" || !valid_trn?(row[0]) + row[0].blank? || row[4] == "NULL" || row[0] == "NULL" || !valid_teacher_reference_number?(row[0]) end - def valid_trn?(trn) - normalize_teacher_reference_number(trn) - valid_trn_length?(trn) + def valid_teacher_reference_number?(trn) + normalised_teacher_reference_number(trn) + valid_teacher_reference_number_length_for_school_workforce_census?(trn) end def row_to_hash(row) diff --git a/app/models/topup.rb b/app/models/topup.rb index b185f8b460..dc746d2a19 100644 --- a/app/models/topup.rb +++ b/app/models/topup.rb @@ -10,12 +10,14 @@ class Topup < ApplicationRecord validates :award_amount, presence: {message: "Enter top up amount"} validate :award_amount_must_be_in_range, on: :create - delegate :teacher_reference_number, to: :claim - def payrolled? payment.present? end + def teacher_reference_number + claim.eligibility.teacher_reference_number + end + private def award_amount_must_be_in_range diff --git a/app/views/admin/amendments/new.html.erb b/app/views/admin/amendments/new.html.erb index 1bf404a300..eab90c3541 100644 --- a/app/views/admin/amendments/new.html.erb +++ b/app/views/admin/amendments/new.html.erb @@ -19,19 +19,21 @@ <%= form_with model: @amendment, url: admin_claim_amendments_path(@claim), html: { autocomplete: "off" } do |f| %> <%= f.fields_for :claim, @amendment.claim do |claim_form| %> -
-
- <%= form_group_tag(@amendment, :teacher_reference_number) do %> - <%= claim_form.label :teacher_reference_number, class: "govuk-label" %> - <%= errors_tag @amendment, :teacher_reference_number %> - <% end %> -
-
-
- <%= claim_form.text_field :teacher_reference_number, class: "govuk-input govuk-input--width-10" %> + <%= claim_form.fields_for :eligibility, @amendment.claim.eligibility, include_id: false do |eligibility_form| %> +
+
+ <%= form_group_tag(@amendment.claim.eligibility, :teacher_reference_number) do %> + <%= eligibility_form.label :teacher_reference_number, class: "govuk-label" %> + <%= errors_tag @amendment.claim.eligibility, :teacher_reference_number %> + <% end %> +
+
+
+ <%= eligibility_form.text_field(:teacher_reference_number, class: "govuk-input govuk-input--width-10") %> +
-
+ <% end %>
diff --git a/app/views/admin/tasks/_claim_summary.html.erb b/app/views/admin/tasks/_claim_summary.html.erb index 9da8f08daf..6197d0c2b5 100644 --- a/app/views/admin/tasks/_claim_summary.html.erb +++ b/app/views/admin/tasks/_claim_summary.html.erb @@ -26,7 +26,7 @@
- <%= claim.teacher_reference_number %> + <%= claim.eligibility.teacher_reference_number %>
diff --git a/config/analytics.yml b/config/analytics.yml index 1f02b9d51d..446c53c6f0 100644 --- a/config/analytics.yml +++ b/config/analytics.yml @@ -151,6 +151,7 @@ shared: - had_leadership_position - mostly_performed_leadership_duties - claim_school_somewhere_else + - teacher_reference_number :early_career_payments_eligibilities: - id - nqt_in_academic_year_after_itt @@ -169,6 +170,7 @@ shared: - award_amount - induction_completed - school_somewhere_else + - teacher_reference_number :levelling_up_premium_payments_eligibilities: - id - created_at @@ -188,6 +190,7 @@ shared: - eligible_degree_subject - induction_completed - school_somewhere_else + - teacher_reference_number :international_relocation_payments_eligibilities: - id - created_at diff --git a/config/brakeman.ignore b/config/brakeman.ignore index 4bf570841b..1e49f435ac 100644 --- a/config/brakeman.ignore +++ b/config/brakeman.ignore @@ -30,7 +30,7 @@ "check_name": "SQL", "message": "Possible SQL injection", "file": "app/models/claim/search.rb", - "line": 28, + "line": 45, "link": "https://brakemanscanner.org/docs/warning_types/sql_injection/", "code": "Claim.submitted.where(\"LOWER(#{attribute}) = LOWER(?)\", search_term)", "render_path": null, @@ -118,13 +118,13 @@ { "warning_type": "SQL Injection", "warning_code": 0, - "fingerprint": "aac74520956533997d73d1c601c2bcde5d3cd501f14401fb9cb8e2bfdc7862fa", + "fingerprint": "f83635b54e1ce0088178d8082ffe632ab8aa81b10fce1026caf87f286cb4d81a", "check_name": "SQL", "message": "Possible SQL injection", "file": "app/models/claim/matching_attribute_finder.rb", - "line": 31, + "line": 54, "link": "https://brakemanscanner.org/docs/warning_types/sql_injection/", - "code": "Claim.where(\"LOWER(#{\"CONCAT(#{attributes.join(\",\")})\"}) = LOWER(?)\", values_for_attributes(attributes).join)", + "code": "Claim.where(\"LOWER(#{\"CONCAT(#{attributes.join(\",\")})\"}) = LOWER(?)\", values_for_attributes(source_claim, attributes).join)", "render_path": null, "location": { "type": "method", @@ -136,55 +136,9 @@ "cwe_id": [ 89 ], - "note": "The concetenated attributes in the CONCAT operation are not user-generated, so this can be safely ignored" - }, - { - "warning_type": "Redirect", - "warning_code": 18, - "fingerprint": "b838db1b7beff28cdeff71a154a46d7c57062fb11aebf82f0487a9991445bea5", - "check_name": "Redirect", - "message": "Possible unprotected redirect", - "file": "app/controllers/concerns/part_of_claim_journey.rb", - "line": 25, - "link": "https://brakemanscanner.org/docs/warning_types/redirect/", - "code": "redirect_to(Journeys::Configuration.start_page_url(current_journey_routing_name), :allow_other_host => true)", - "render_path": null, - "location": { - "type": "method", - "class": "PartOfClaimJourney", - "method": "send_unstarted_claimants_to_the_start" - }, - "user_input": "Journeys::Configuration.start_page_url(current_journey_routing_name)", - "confidence": "Weak", - "cwe_id": [ - 601 - ], - "note": "" - }, - { - "warning_type": "Redirect", - "warning_code": 18, - "fingerprint": "d7efbb65a649f824e34aa86f2d844a9d5ffac945eea04198f59418ac1998721c", - "check_name": "Redirect", - "message": "Possible unprotected redirect", - "file": "app/controllers/submissions_controller.rb", - "line": 22, - "link": "https://brakemanscanner.org/docs/warning_types/redirect/", - "code": "redirect_to(Journeys::Configuration.start_page_url(current_journey_routing_name), :allow_other_host => true)", - "render_path": null, - "location": { - "type": "method", - "class": "SubmissionsController", - "method": "show" - }, - "user_input": "Journeys::Configuration.start_page_url(current_journey_routing_name)", - "confidence": "Weak", - "cwe_id": [ - 601 - ], "note": "" } ], - "updated": "2024-03-07 12:34:07 +0000", + "updated": "2024-06-20 16:06:05 +0100", "brakeman_version": "6.1.2" } diff --git a/db/migrate/20240511100914_move_teacher_reference_number_to_eligibility.rb b/db/migrate/20240511100914_move_teacher_reference_number_to_eligibility.rb new file mode 100644 index 0000000000..557ac81636 --- /dev/null +++ b/db/migrate/20240511100914_move_teacher_reference_number_to_eligibility.rb @@ -0,0 +1,19 @@ +class MoveTeacherReferenceNumberToEligibility < ActiveRecord::Migration[7.0] + def change + add_column :early_career_payments_eligibilities, :teacher_reference_number, :string, limit: 11 + add_column :levelling_up_premium_payments_eligibilities, :teacher_reference_number, :string, limit: 11 + add_column :student_loans_eligibilities, :teacher_reference_number, :string, limit: 11 + + add_index :early_career_payments_eligibilities, :teacher_reference_number, name: "index_ecp_eligibility_trn" + add_index :levelling_up_premium_payments_eligibilities, :teacher_reference_number, name: "index_lupp_eligibility_trn" + add_index :student_loans_eligibilities, :teacher_reference_number, name: "index_sl_eligibility_trn" + + # Copy teacher_reference_number from Claim to Eligibility + Claim.all.includes(:eligibility).each do |claim| + claim.eligibility.update!(teacher_reference_number: claim.teacher_reference_number) + end + + # Keep the old column but rename it so it's not accidentally used, needs removing soon after migration is successful + rename_column :claims, :teacher_reference_number, :column_to_remove_teacher_reference_number + end +end diff --git a/db/schema.rb b/db/schema.rb index 2bbacefc1c..2db075d1f0 100644 --- a/db/schema.rb +++ b/db/schema.rb @@ -49,7 +49,7 @@ t.string "address_line_4", limit: 100 t.string "postcode", limit: 11 t.date "date_of_birth" - t.string "teacher_reference_number", limit: 11 + t.string "column_to_remove_teacher_reference_number", limit: 11 t.string "national_insurance_number", limit: 9 t.string "email_address", limit: 256 t.string "bank_sort_code", limit: 6 @@ -170,7 +170,9 @@ t.decimal "award_amount", precision: 7, scale: 2 t.boolean "induction_completed" t.boolean "school_somewhere_else" + t.string "teacher_reference_number", limit: 11 t.index ["current_school_id"], name: "index_early_career_payments_eligibilities_on_current_school_id" + t.index ["teacher_reference_number"], name: "index_ecp_eligibility_trn" end create_table "file_uploads", id: :uuid, default: -> { "gen_random_uuid()" }, force: :cascade do |t| @@ -246,7 +248,9 @@ t.boolean "eligible_degree_subject" t.boolean "induction_completed" t.boolean "school_somewhere_else" + t.string "teacher_reference_number", limit: 11 t.index ["current_school_id"], name: "index_lup_payments_eligibilities_on_current_school_id" + t.index ["teacher_reference_number"], name: "index_lupp_eligibility_trn" end create_table "local_authorities", id: :uuid, default: -> { "gen_random_uuid()" }, force: :cascade do |t| @@ -406,9 +410,11 @@ t.boolean "had_leadership_position" t.boolean "mostly_performed_leadership_duties" t.boolean "claim_school_somewhere_else" + t.string "teacher_reference_number", limit: 11 t.index ["claim_school_id"], name: "index_student_loans_eligibilities_on_claim_school_id" t.index ["created_at"], name: "index_student_loans_eligibilities_on_created_at" t.index ["current_school_id"], name: "index_student_loans_eligibilities_on_current_school_id" + t.index ["teacher_reference_number"], name: "index_sl_eligibility_trn" end create_table "support_tickets", id: :uuid, default: -> { "gen_random_uuid()" }, force: :cascade do |t| diff --git a/spec/factories/amendments.rb b/spec/factories/amendments.rb index e1ba30273b..0abe1b5004 100644 --- a/spec/factories/amendments.rb +++ b/spec/factories/amendments.rb @@ -2,12 +2,12 @@ factory :amendment do association :claim, factory: [:claim, :submitted] association :created_by, factory: :dfe_signin_user - claim_changes { {"teacher_reference_number" => [generate(:teacher_reference_number).to_s, claim.teacher_reference_number]} } + claim_changes { {"teacher_reference_number" => [generate(:teacher_reference_number).to_s, claim.eligibility.teacher_reference_number]} } notes { "We couldn’t find the teacher in Teacher Pensions Service data. We contacted them in Zendesk and they told us they made a typo and gave their correct TRN" } trait :personal_data_removed do personal_data_removed_at { Time.zone.now } - claim_changes { {"teacher_reference_number" => [generate(:teacher_reference_number).to_s, claim.teacher_reference_number], "bank_account_number" => nil} } + claim_changes { {"teacher_reference_number" => [generate(:teacher_reference_number).to_s, claim.eligibility.teacher_reference_number], "bank_account_number" => nil} } end end end diff --git a/spec/factories/claims.rb b/spec/factories/claims.rb index 71ee639506..22579f1c9a 100644 --- a/spec/factories/claims.rb +++ b/spec/factories/claims.rb @@ -39,7 +39,6 @@ trait :with_details_from_dfe_identity do first_name { "Jo" } surname { "Bloggs" } - teacher_reference_number { generate(:teacher_reference_number) } date_of_birth { 20.years.ago.to_date } national_insurance_number { generate(:national_insurance_number) } end diff --git a/spec/factories/early_career_payments/eligibilities.rb b/spec/factories/early_career_payments/eligibilities.rb index 269b369b67..dfcccd38df 100644 --- a/spec/factories/early_career_payments/eligibilities.rb +++ b/spec/factories/early_career_payments/eligibilities.rb @@ -3,6 +3,7 @@ award_amount { 5000.0 } trait :eligible do + teacher_reference_number { generate(:teacher_reference_number) } eligible_now end diff --git a/spec/factories/levelling_up_premium_payments/eligibilities.rb b/spec/factories/levelling_up_premium_payments/eligibilities.rb index f9e81c8a55..e387e12253 100644 --- a/spec/factories/levelling_up_premium_payments/eligibilities.rb +++ b/spec/factories/levelling_up_premium_payments/eligibilities.rb @@ -2,7 +2,8 @@ factory :levelling_up_premium_payments_eligibility, class: "Policies::LevellingUpPremiumPayments::Eligibility" do award_amount { 2000.0 } - trait :eligible do # TODO rename + trait :eligible do + teacher_reference_number { generate(:teacher_reference_number) } eligible_now end diff --git a/spec/factories/payments.rb b/spec/factories/payments.rb index e866c32dc3..991361a4d9 100644 --- a/spec/factories/payments.rb +++ b/spec/factories/payments.rb @@ -7,10 +7,10 @@ claims do personal_details = { national_insurance_number: generate(:national_insurance_number), - teacher_reference_number: generate(:teacher_reference_number), email_address: "email@example.com", bank_sort_code: "220011", - bank_account_number: "12345678" + bank_account_number: "12345678", + eligibility_attributes: {teacher_reference_number: generate(:teacher_reference_number)} } claim_policies.map do |policy| association(:claim, :approved, personal_details.merge(policy: policy)) diff --git a/spec/factories/student_loans/eligibilities.rb b/spec/factories/student_loans/eligibilities.rb index 95e5a21523..bdb969d62b 100644 --- a/spec/factories/student_loans/eligibilities.rb +++ b/spec/factories/student_loans/eligibilities.rb @@ -11,6 +11,7 @@ had_leadership_position { true } mostly_performed_leadership_duties { false } student_loan_repayment_amount { 1000 } + teacher_reference_number { generate(:teacher_reference_number) } end trait :ineligible do diff --git a/spec/features/admin_amend_claim_spec.rb b/spec/features/admin_amend_claim_spec.rb index 872e13534b..5323c37668 100644 --- a/spec/features/admin_amend_claim_spec.rb +++ b/spec/features/admin_amend_claim_spec.rb @@ -8,7 +8,7 @@ RSpec.feature "Admin amends a claim" do let(:claim) do create(:claim, :submitted, - teacher_reference_number: "1234567", + eligibility_attributes: {teacher_reference_number: "1234567"}, payroll_gender: :dont_know, date_of_birth: date_of_birth, student_loan_plan: :plan_1, @@ -57,7 +57,7 @@ expect(amendment.notes).to eq("This claimant got some of their details wrong and then contacted us") expect(amendment.created_by).to eq(@signed_in_user) - expect(claim.reload.teacher_reference_number).to eq("7654321") + expect(claim.eligibility.reload.teacher_reference_number).to eq("7654321") expect(claim.date_of_birth).to eq(new_date_of_birth) expect(claim.student_loan_plan).to eq("plan_2") expect(claim.bank_sort_code).to eq("111213") @@ -88,7 +88,7 @@ fill_in "Teacher reference number", with: "7654321" - expect { click_on "Cancel" }.not_to change { [claim.reload.amendments.size, claim.teacher_reference_number] } + expect { click_on "Cancel" }.not_to change { [claim.reload.amendments.size, claim.eligibility.teacher_reference_number] } expect(current_url).to eq(admin_claim_tasks_url(claim)) end diff --git a/spec/features/admin_claim_tasks_update_with_dqt_api_spec.rb b/spec/features/admin_claim_tasks_update_with_dqt_api_spec.rb index c06d689435..77639b8b7f 100644 --- a/spec/features/admin_claim_tasks_update_with_dqt_api_spec.rb +++ b/spec/features/admin_claim_tasks_update_with_dqt_api_spec.rb @@ -110,7 +110,7 @@ def task_outcome status = 200 end - stub_request(:get, "#{ENV["DQT_API_URL"]}teachers/#{claim.teacher_reference_number}") + stub_request(:get, "#{ENV["DQT_API_URL"]}teachers/#{claim.eligibility.teacher_reference_number}") .with(query: WebMock::API.hash_including({ birthdate: claim.date_of_birth.to_s, nino: claim.national_insurance_number @@ -173,7 +173,7 @@ def task_outcome date_of_birth: claim.date_of_birth, name: "#{claim.first_name} #{claim.surname}", national_insurance_number: claim.national_insurance_number, - teacher_reference_number: claim.teacher_reference_number + teacher_reference_number: claim.eligibility.teacher_reference_number } end @@ -211,7 +211,7 @@ def task_outcome date_of_birth: claim.date_of_birth, name: "#{claim.first_name} #{claim.surname}", national_insurance_number: "QQ100000B", - teacher_reference_number: claim.teacher_reference_number + teacher_reference_number: claim.eligibility.teacher_reference_number } end @@ -290,7 +290,7 @@ def task_outcome scenario "shows the notes added as part of automated identity checking" do expect(notes).to include( have_text("Teacher reference number not matched").and( - have_text("Claimant: \"#{claim.teacher_reference_number}\"").and( + have_text("Claimant: \"#{claim.eligibility.teacher_reference_number}\"").and( have_text("DQT: \"7654321\"").and( have_text("by an automated check") ) @@ -319,7 +319,7 @@ def task_outcome date_of_birth: claim.date_of_birth, name: "Except #{claim.surname}", national_insurance_number: claim.national_insurance_number, - teacher_reference_number: claim.teacher_reference_number + teacher_reference_number: claim.eligibility.teacher_reference_number } end @@ -375,7 +375,7 @@ def task_outcome date_of_birth: claim.date_of_birth, name: "#{claim.first_name} Except", national_insurance_number: claim.national_insurance_number, - teacher_reference_number: claim.teacher_reference_number + teacher_reference_number: claim.eligibility.teacher_reference_number } end @@ -431,7 +431,7 @@ def task_outcome date_of_birth: claim.date_of_birth, name: "#{claim.first_name} Middle Names #{claim.surname}", national_insurance_number: claim.national_insurance_number, - teacher_reference_number: claim.teacher_reference_number + teacher_reference_number: claim.eligibility.teacher_reference_number } end @@ -470,7 +470,7 @@ def task_outcome date_of_birth: claim.date_of_birth + 1.day, name: "#{claim.first_name} #{claim.surname}", national_insurance_number: claim.national_insurance_number, - teacher_reference_number: claim.teacher_reference_number + teacher_reference_number: claim.eligibility.teacher_reference_number } end @@ -568,7 +568,7 @@ def task_outcome date_of_birth: claim.date_of_birth, name: "#{claim.first_name} #{claim.surname}", national_insurance_number: claim.national_insurance_number, - teacher_reference_number: claim.teacher_reference_number + teacher_reference_number: claim.eligibility.teacher_reference_number } end @@ -626,7 +626,7 @@ def task_outcome date_of_birth: claim.date_of_birth + 1.day, name: "Except #{claim.surname}", national_insurance_number: claim.national_insurance_number, - teacher_reference_number: claim.teacher_reference_number + teacher_reference_number: claim.eligibility.teacher_reference_number } end @@ -1008,7 +1008,7 @@ def task_outcome date_of_birth: claim.date_of_birth, name: "#{claim.first_name} #{claim.surname}", national_insurance_number: claim.national_insurance_number, - teacher_reference_number: claim.teacher_reference_number + teacher_reference_number: claim.eligibility.teacher_reference_number } end @@ -1046,7 +1046,7 @@ def task_outcome date_of_birth: claim.date_of_birth, name: "#{claim.first_name} #{claim.surname}", national_insurance_number: "QQ100000B", - teacher_reference_number: claim.teacher_reference_number + teacher_reference_number: claim.eligibility.teacher_reference_number } end @@ -1125,7 +1125,7 @@ def task_outcome scenario "shows the notes added as part of automated identity checking" do expect(notes).to include( have_text("Teacher reference number not matched").and( - have_text("Claimant: \"#{claim.teacher_reference_number}\"").and( + have_text("Claimant: \"#{claim.eligibility.teacher_reference_number}\"").and( have_text("DQT: \"7654321\"").and( have_text("by an automated check") ) @@ -1154,7 +1154,7 @@ def task_outcome date_of_birth: claim.date_of_birth, name: "Except #{claim.surname}", national_insurance_number: claim.national_insurance_number, - teacher_reference_number: claim.teacher_reference_number + teacher_reference_number: claim.eligibility.teacher_reference_number } end @@ -1210,7 +1210,7 @@ def task_outcome date_of_birth: claim.date_of_birth, name: "#{claim.first_name} Except", national_insurance_number: claim.national_insurance_number, - teacher_reference_number: claim.teacher_reference_number + teacher_reference_number: claim.eligibility.teacher_reference_number } end @@ -1270,7 +1270,7 @@ def task_outcome date_of_birth: claim.date_of_birth, name: "#{claim.first_name} Middle Names #{claim.surname}", national_insurance_number: claim.national_insurance_number, - teacher_reference_number: claim.teacher_reference_number + teacher_reference_number: claim.eligibility.teacher_reference_number } end @@ -1309,7 +1309,7 @@ def task_outcome date_of_birth: claim.date_of_birth + 1.day, name: "#{claim.first_name} #{claim.surname}", national_insurance_number: claim.national_insurance_number, - teacher_reference_number: claim.teacher_reference_number + teacher_reference_number: claim.eligibility.teacher_reference_number } end @@ -1407,7 +1407,7 @@ def task_outcome date_of_birth: claim.date_of_birth, name: "#{claim.first_name} #{claim.surname}", national_insurance_number: claim.national_insurance_number, - teacher_reference_number: claim.teacher_reference_number + teacher_reference_number: claim.eligibility.teacher_reference_number } end @@ -1461,7 +1461,7 @@ def task_outcome date_of_birth: claim.date_of_birth + 1.day, name: "Except #{claim.surname}", national_insurance_number: claim.national_insurance_number, - teacher_reference_number: claim.teacher_reference_number + teacher_reference_number: claim.eligibility.teacher_reference_number } end diff --git a/spec/features/admin_claim_with_inconsistent_payroll_information_spec.rb b/spec/features/admin_claim_with_inconsistent_payroll_information_spec.rb index 8763cd636c..e4c343df56 100644 --- a/spec/features/admin_claim_with_inconsistent_payroll_information_spec.rb +++ b/spec/features/admin_claim_with_inconsistent_payroll_information_spec.rb @@ -4,7 +4,7 @@ let(:personal_details) do { national_insurance_number: generate(:national_insurance_number), - teacher_reference_number: generate(:teacher_reference_number), + eligibility_attributes: {teacher_reference_number: generate(:teacher_reference_number)}, date_of_birth: 30.years.ago.to_date, student_loan_plan: StudentLoan::PLAN_1, email_address: "email@example.com", diff --git a/spec/features/admin_claim_with_matching_details_spec.rb b/spec/features/admin_claim_with_matching_details_spec.rb index c77a32b59c..bb2220b9f5 100644 --- a/spec/features/admin_claim_with_matching_details_spec.rb +++ b/spec/features/admin_claim_with_matching_details_spec.rb @@ -9,7 +9,7 @@ scenario "service operator can check a claim with matching details" do claim = create(:claim, :submitted, policy: Policies::StudentLoans) - claim_with_matching_details = create(:claim, :submitted, teacher_reference_number: claim.teacher_reference_number) + claim_with_matching_details = create(:claim, :submitted, eligibility_attributes: {teacher_reference_number: claim.eligibility.teacher_reference_number}) click_on "View claims" find("a[href='#{admin_claim_tasks_path(claim)}']").click diff --git a/spec/features/admin_data_report_request_spec.rb b/spec/features/admin_data_report_request_spec.rb index 4453b1b065..c34b3300a4 100644 --- a/spec/features/admin_data_report_request_spec.rb +++ b/spec/features/admin_data_report_request_spec.rb @@ -32,7 +32,7 @@ csv.each_with_index do |row, i| claim = claims.detect { |c| c.reference == row["Claim reference"] } expect(claim).not_to be_nil - expect(row["Teacher reference number"]).to eq(claim.teacher_reference_number) + expect(row["Teacher reference number"]).to eq(claim.eligibility.teacher_reference_number) expect(row["NINO"]).to eq(claim.national_insurance_number) expect(row["Full name"]).to eq(claim.full_name) expect(row["Email"]).to eq(claim.email_address) diff --git a/spec/features/admin_search_spec.rb b/spec/features/admin_search_spec.rb index 0a5b5f8735..98d61a1af5 100644 --- a/spec/features/admin_search_spec.rb +++ b/spec/features/admin_search_spec.rb @@ -18,7 +18,7 @@ expect(page).to have_content(claim1.reference) expect(page).to have_no_content(claim2.reference) - expect(page).to have_content(claim1.teacher_reference_number) + expect(page).to have_content(claim1.eligibility.teacher_reference_number) expect(page).to have_content(claim1.policy.short_name) end @@ -35,7 +35,7 @@ expect(page).to have_content(claim1.reference) expect(page).to have_no_content(claim2.reference) - expect(page).to have_content(claim1.teacher_reference_number) + expect(page).to have_content(claim1.eligibility.teacher_reference_number) expect(page).to have_content(claim1.policy.short_name) end diff --git a/spec/features/early_career_payments_claim_spec.rb b/spec/features/early_career_payments_claim_spec.rb index 547d2a803e..75d65d87b5 100644 --- a/spec/features/early_career_payments_claim_spec.rb +++ b/spec/features/early_career_payments_claim_spec.rb @@ -246,7 +246,7 @@ expect(claim.bank_sort_code).to eq("123456") expect(claim.bank_account_number).to eq("87654321") expect(claim.payroll_gender).to eq("female") - expect(claim.teacher_reference_number).to eq("1234567") + expect(claim.eligibility.teacher_reference_number).to eq("1234567") expect(claim.reload.submitted_at).to eq(Time.zone.now) policy_options_provided = [ {"policy" => "EarlyCareerPayments", "award_amount" => "5000.0"}, @@ -655,7 +655,7 @@ expect(claim.bank_sort_code).to eq("123456") expect(claim.bank_account_number).to eq("87654321") expect(claim.payroll_gender).to eq("female") - expect(claim.teacher_reference_number).to eql("1234567") + expect(claim.eligibility.teacher_reference_number).to eql("1234567") expect(claim.submitted_at).to eq(Time.zone.now) policy_options_provided = [ {"policy" => "EarlyCareerPayments", "award_amount" => "5000.0"}, @@ -965,7 +965,7 @@ expect(submitted_claim.bank_sort_code).to eq("123456") expect(submitted_claim.bank_account_number).to eq("87654321") expect(submitted_claim.payroll_gender).to eq("female") - expect(submitted_claim.teacher_reference_number).to eql("1234567") + expect(submitted_claim.eligibility.teacher_reference_number).to eql("1234567") expect(submitted_claim.submitted_at).to eq(Time.zone.now) policy_options_provided = [ diff --git a/spec/features/levelling_up_premium_payments_spec.rb b/spec/features/levelling_up_premium_payments_spec.rb index 9ae995d42a..9e716ec98f 100644 --- a/spec/features/levelling_up_premium_payments_spec.rb +++ b/spec/features/levelling_up_premium_payments_spec.rb @@ -251,7 +251,7 @@ def submit_application expect(submitted_claim.bank_sort_code).to eq("123456") expect(submitted_claim.bank_account_number).to eq("87654321") expect(submitted_claim.payroll_gender).to eq("female") - expect(submitted_claim.teacher_reference_number).to eql("1234567") + expect(submitted_claim.eligibility.teacher_reference_number).to eql("1234567") # - Application complete (make sure its Word for Word and styling matches) expect(page).to have_text("You applied for a levelling up premium payment") diff --git a/spec/helpers/admin/claims_helper_spec.rb b/spec/helpers/admin/claims_helper_spec.rb index 12add2e93e..432dfb5ae7 100644 --- a/spec/helpers/admin/claims_helper_spec.rb +++ b/spec/helpers/admin/claims_helper_spec.rb @@ -10,14 +10,14 @@ :claim, first_name: "Bruce", surname: "Wayne", - teacher_reference_number: "1234567", national_insurance_number: "QQ123456C", email_address: "test@email.com", address_line_1: "Flat 1", address_line_2: "1 Test Road", address_line_3: "Test Town", postcode: "AB1 2CD", - date_of_birth: Date.new(1901, 1, 1) + date_of_birth: Date.new(1901, 1, 1), + eligibility_attributes: {teacher_reference_number: "1234567"} ) end @@ -35,7 +35,7 @@ end context "when a claim has had personal data deleted" do - let(:claim) { build(:claim, :rejected, :personal_data_removed, teacher_reference_number: "1234567", email_address: "test@email.com") } + let(:claim) { build(:claim, :rejected, :personal_data_removed, eligibility_attributes: {teacher_reference_number: "1234567"}, email_address: "test@email.com") } it "returns the expected strings" do expected_answers = [ @@ -176,23 +176,23 @@ let(:first_claim) { build( :claim, - teacher_reference_number: "0902344", national_insurance_number: "QQ891011C", email_address: "genghis.khan@mongol-empire.com", bank_account_number: "34682151", bank_sort_code: "972654", - building_society_roll_number: "123456789/ABCD" + building_society_roll_number: "123456789/ABCD", + eligibility_attributes: {teacher_reference_number: "0902344"} ) } let(:second_claim) { build( :claim, :submitted, - teacher_reference_number: first_claim.teacher_reference_number, national_insurance_number: first_claim.national_insurance_number, bank_account_number: first_claim.bank_account_number, bank_sort_code: first_claim.bank_sort_code, - building_society_roll_number: first_claim.building_society_roll_number + building_society_roll_number: first_claim.building_society_roll_number, + eligibility_attributes: {teacher_reference_number: first_claim.eligibility.teacher_reference_number} ) } subject { helper.matching_attributes(first_claim, second_claim) } diff --git a/spec/jobs/qualifications_no_match_check_job_spec.rb b/spec/jobs/qualifications_no_match_check_job_spec.rb index 0e81933d01..78868de968 100644 --- a/spec/jobs/qualifications_no_match_check_job_spec.rb +++ b/spec/jobs/qualifications_no_match_check_job_spec.rb @@ -3,7 +3,7 @@ RSpec.describe QualificationsNoMatchCheckJob do before do stub_qualified_teaching_statuses_show( - trn: claim.teacher_reference_number, + trn: claim.eligibility.teacher_reference_number, params: { birthdate: claim.date_of_birth&.to_s, nino: claim.national_insurance_number diff --git a/spec/mailers/payment_mailer_spec.rb b/spec/mailers/payment_mailer_spec.rb index de81bcf57c..90e3f04de0 100644 --- a/spec/mailers/payment_mailer_spec.rb +++ b/spec/mailers/payment_mailer_spec.rb @@ -96,18 +96,17 @@ context "with a payment with multiple claims" do describe "#confirmation" do let(:payment) { create(:payment, :confirmed, :with_figures, net_pay: 2500.00, student_loan_repayment: 60, claims: claims, scheduled_payment_date: Date.parse("2019-01-01")) } - let(:student_loans_eligibility) { build(:student_loans_eligibility, :eligible, student_loan_repayment_amount: 500) } + let(:teacher_reference_number) { "1234567" } let(:claims) do personal_details = { national_insurance_number: "JM603818B", - teacher_reference_number: "1234567", bank_sort_code: "112233", bank_account_number: "95928482", building_society_roll_number: nil } [ - build(:claim, :approved, personal_details.merge(eligibility: student_loans_eligibility)), - build(:claim, :approved, personal_details.merge(policy: Policies::EarlyCareerPayments)) + build(:claim, :approved, personal_details.merge(eligibility_attributes: {student_loan_repayment_amount: 500, teacher_reference_number: teacher_reference_number})), + build(:claim, :approved, personal_details.merge(policy: Policies::EarlyCareerPayments, eligibility_attributes: {teacher_reference_number: teacher_reference_number})) ] end let(:mail) { PaymentMailer.confirmation(payment) } diff --git a/spec/models/amendment_spec.rb b/spec/models/amendment_spec.rb index 7bc5388869..17d11794d0 100644 --- a/spec/models/amendment_spec.rb +++ b/spec/models/amendment_spec.rb @@ -33,7 +33,7 @@ let(:claim) { create(:claim, :submitted, - teacher_reference_number: "1234567", + eligibility_attributes: {teacher_reference_number: "1234567"}, bank_sort_code: "111213", bank_account_number: "12345678", building_society_roll_number: nil, @@ -45,7 +45,7 @@ context "given valid claim attributes and valid amendment attributes" do let(:claim_attributes) do { - teacher_reference_number: "7654321", + eligibility_attributes: {teacher_reference_number: "7654321"}, bank_account_number: "87654321" } end @@ -66,7 +66,7 @@ expect(amendment.created_by).to eq(dfe_signin_user) expect(claim.reload.amendments).to eq([amendment]) - expect(claim.teacher_reference_number).to eq("7654321") + expect(claim.eligibility.teacher_reference_number).to eq("7654321") expect(claim.bank_account_number).to eq("87654321") end end @@ -74,7 +74,7 @@ context "given valid claim attributes and missing amendment notes" do let(:claim_attributes) do { - teacher_reference_number: "7654321", + eligibility_attributes: {teacher_reference_number: "7654321"}, bank_account_number: "87654321" } end @@ -92,11 +92,11 @@ expect(amendment.claim_changes).to eq("teacher_reference_number" => ["1234567", "7654321"], "bank_account_number" => ["12345678", "87654321"]) expect(amendment.created_by).to eq(dfe_signin_user) - expect(claim.teacher_reference_number).to eq("7654321") + expect(claim.eligibility.teacher_reference_number).to eq("7654321") expect(claim.bank_account_number).to eq("87654321") expect(claim.reload.amendments).to be_empty - expect(claim.teacher_reference_number).to eq("1234567") + expect(claim.eligibility.teacher_reference_number).to eq("1234567") expect(claim.bank_account_number).to eq("12345678") expect(amendment.errors.attribute_names).to eq([:notes]) @@ -106,7 +106,7 @@ context "given invalid claim attributes and valid amendment attributes" do let(:claim_attributes) do { - teacher_reference_number: "765432", + eligibility_attributes: {teacher_reference_number: "765432"}, bank_account_number: "87654321" } end @@ -117,27 +117,58 @@ } end - it "assigns the new values to the claim but does not persist them, and returns a non-persisted amendment, with the errors from the claim copied to the amendment’s errors" do + it "assigns the new values to the claim but does not persist them, and returns a non-persisted amendment, with the errors from the claim copied to the amendment's errors" do amendment = described_class.amend_claim(claim, claim_attributes, amendment_attributes) expect(amendment).to_not be_persisted expect(amendment.created_by).to eq(dfe_signin_user) - expect(claim.teacher_reference_number).to eq("765432") + expect(claim.eligibility.teacher_reference_number).to eq("765432") expect(claim.bank_account_number).to eq("87654321") expect(claim.reload.amendments).to be_empty - expect(claim.teacher_reference_number).to eq("1234567") + expect(claim.eligibility.teacher_reference_number).to eq("1234567") expect(claim.bank_account_number).to eq("12345678") - expect(amendment.errors.attribute_names).to match_array([:teacher_reference_number]) + expect(amendment.errors.attribute_names).to match_array([:"eligibility.teacher_reference_number"]) + end + end + + context "given invalid claim attributes (blank trn) and valid amendment attributes" do + let(:claim_attributes) do + { + eligibility_attributes: {teacher_reference_number: ""}, + bank_account_number: "87654321" + } + end + let(:amendment_attributes) do + { + notes: "This is a change", + created_by: dfe_signin_user + } + end + + it "assigns the new values to the claim but does not persist them, and returns a non-persisted amendment, with the errors from the claim copied to the amendment's errors" do + amendment = described_class.amend_claim(claim, claim_attributes, amendment_attributes) + + expect(amendment).to_not be_persisted + expect(amendment.created_by).to eq(dfe_signin_user) + + expect(claim.eligibility.teacher_reference_number).to eq("") + expect(claim.bank_account_number).to eq("87654321") + + expect(claim.reload.amendments).to be_empty + expect(claim.eligibility.teacher_reference_number).to eq("1234567") + expect(claim.bank_account_number).to eq("12345678") + + expect(amendment.errors.attribute_names).to match_array([:"eligibility.teacher_reference_number"]) end end context "given invalid claim attributes and missing amendment notes" do let(:claim_attributes) do { - teacher_reference_number: "765432", + eligibility_attributes: {teacher_reference_number: "765432"}, bank_account_number: "87654321" } end @@ -147,27 +178,27 @@ } end - it "assigns the new values to the claim but does not persist them, and returns a non-persisted amendment which has errors, with the errors from the claim copied to the amendment’s errors" do + it "assigns the new values to the claim but does not persist them, and returns a non-persisted amendment which has errors, with the errors from the claim copied to the amendment's errors" do amendment = described_class.amend_claim(claim, claim_attributes, amendment_attributes) expect(amendment).to_not be_persisted expect(amendment.created_by).to eq(dfe_signin_user) - expect(claim.teacher_reference_number).to eq("765432") + expect(claim.eligibility.teacher_reference_number).to eq("765432") expect(claim.bank_account_number).to eq("87654321") expect(claim.reload.amendments).to be_empty - expect(claim.teacher_reference_number).to eq("1234567") + expect(claim.eligibility.teacher_reference_number).to eq("1234567") expect(claim.bank_account_number).to eq("12345678") - expect(amendment.errors.attribute_names).to match_array([:notes, :teacher_reference_number]) + expect(amendment.errors.attribute_names).to match_array([:notes, :"eligibility.teacher_reference_number"]) end end context "given claim attributes which are all the same as the current values" do let(:claim_attributes) do { - teacher_reference_number: claim.teacher_reference_number + eligibility_attributes: {teacher_reference_number: claim.eligibility.teacher_reference_number} } end let(:amendment_attributes) do @@ -178,7 +209,7 @@ end it "returns a non-persisted amendment which has errors on claim_changes" do - amendment = described_class.amend_claim(claim, claim_attributes, amendment_attributes) + amendment = described_class.amend_claim(claim.reload, claim_attributes, amendment_attributes) expect(amendment).to_not be_persisted expect(claim.reload.amendments).to be_empty @@ -200,14 +231,14 @@ } end - it "stores the normalised value in the amendment’s claim_changes" do - amendment = described_class.amend_claim(claim, claim_attributes, amendment_attributes) + it "stores the normalised value in the amendment's claim_changes" do + amendment = described_class.amend_claim(claim.reload, claim_attributes, amendment_attributes) expect(amendment.claim_changes).to eq("bank_sort_code" => ["111213", "010203"]) end end - context "when amending the claim’s eligibility attributes" do + context "when amending the claim's eligibility attributes" do context "with a Student Loans (TSLR) claim" do let(:claim) do create(:claim, :submitted, eligibility: build(:student_loans_eligibility, :eligible, student_loan_repayment_amount: 1000)) @@ -215,9 +246,7 @@ let(:claim_attributes) do { - eligibility_attributes: { - student_loan_repayment_amount: 555 - } + eligibility_attributes: {student_loan_repayment_amount: 555} } end let(:amendment_attributes) do @@ -227,8 +256,8 @@ } end - it "stores the value in the amendment’s claim_changes" do - amendment = described_class.amend_claim(claim, claim_attributes, amendment_attributes) + it "stores the value in the amendment's claim_changes" do + amendment = described_class.amend_claim(claim.reload, claim_attributes, amendment_attributes) expect(amendment.claim_changes).to eq("student_loan_repayment_amount" => [1000, 555]) end @@ -295,7 +324,7 @@ before { create(:journey_configuration, :additional_payments) } - it "stores the value in the amendment’s claim_changes" do + it "stores the value in the amendment's claim_changes" do amendment = described_class.amend_claim(claim, claim_attributes, amendment_attributes) expect(amendment.claim_changes).to eq("award_amount" => [7_500, 2_500]) @@ -306,7 +335,7 @@ context "when updating a value from nil to an empty string" do let(:claim_attributes) do { - teacher_reference_number: "7654321", + eligibility_attributes: {teacher_reference_number: "7654321"}, building_society_roll_number: "" } end @@ -317,7 +346,7 @@ } end - it "does not mark the value as changed in the amendment’s claim_changes" do + it "does not mark the value as changed in the amendment's claim_changes" do amendment = described_class.amend_claim(claim, claim_attributes, amendment_attributes) expect(amendment.claim_changes).to eq("teacher_reference_number" => ["1234567", "7654321"]) diff --git a/spec/models/automated_checks/claim_verifiers/census_subjects_taught_spec.rb b/spec/models/automated_checks/claim_verifiers/census_subjects_taught_spec.rb index 0261efb5e5..48dd56f4ac 100644 --- a/spec/models/automated_checks/claim_verifiers/census_subjects_taught_spec.rb +++ b/spec/models/automated_checks/claim_verifiers/census_subjects_taught_spec.rb @@ -14,7 +14,6 @@ module ClaimVerifiers national_insurance_number: "RT901113D", reference: "QKCVAQ3K", surname: "Bonnet-Fontaine", - teacher_reference_number: teacher_reference_number, policy: policy ) @@ -23,7 +22,8 @@ module ClaimVerifiers attributes_for( :"#{policy_underscored}_eligibility", :eligible, - eligible_itt_subject: :mathematics + eligible_itt_subject: :mathematics, + teacher_reference_number: teacher_reference_number ) ) elsif policy == Policies::LevellingUpPremiumPayments @@ -31,7 +31,8 @@ module ClaimVerifiers attributes_for( :"#{policy_underscored}_eligibility", :eligible, - eligible_itt_subject: :computing + eligible_itt_subject: :computing, + teacher_reference_number: teacher_reference_number ) ) elsif policy == Policies::StudentLoans @@ -41,7 +42,8 @@ module ClaimVerifiers :eligible, biology_taught: true, computing_taught: true, - physics_taught: false + physics_taught: false, + teacher_reference_number: teacher_reference_number ) ) end @@ -89,7 +91,6 @@ module ClaimVerifiers national_insurance_number: "RT901113D", reference: "QKCVAQ3K", surname: "Bonnet-Fontaine", - teacher_reference_number: teacher_reference_number, policy: policy ) @@ -98,7 +99,8 @@ module ClaimVerifiers attributes_for( :"#{policy_underscored}_eligibility", :eligible, - eligible_itt_subject: :none_of_the_above + eligible_itt_subject: :none_of_the_above, + teacher_reference_number: teacher_reference_number ) ) elsif policy == Policies::LevellingUpPremiumPayments @@ -106,7 +108,8 @@ module ClaimVerifiers attributes_for( :"#{policy_underscored}_eligibility", :eligible, - eligible_itt_subject: :none_of_the_above + eligible_itt_subject: :none_of_the_above, + teacher_reference_number: teacher_reference_number ) ) elsif policy == Policies::StudentLoans @@ -116,7 +119,8 @@ module ClaimVerifiers :eligible, biology_taught: false, computing_taught: false, - physics_taught: false + physics_taught: false, + teacher_reference_number: teacher_reference_number ) ) end @@ -344,9 +348,9 @@ module ClaimVerifiers national_insurance_number: "RT901113D", reference: "QKCVAQ3K", surname: "Bonnet-Fontaine", - teacher_reference_number: teacher_reference_number, policy: policy, - tasks: [build(:task, name: :census_subjects_taught)] + tasks: [build(:task, name: :census_subjects_taught)], + eligibility_attributes: {teacher_reference_number: teacher_reference_number} ) end @@ -405,7 +409,6 @@ module ClaimVerifiers national_insurance_number: "RT901113D", reference: "QKCVAQ3K", surname: "Bonnet-Fontaine", - teacher_reference_number: teacher_reference_number, policy: Policies::StudentLoans ) @@ -416,7 +419,8 @@ module ClaimVerifiers biology_taught: false, computing_taught: false, physics_taught: false, - languages_taught: true + languages_taught: true, + teacher_reference_number: teacher_reference_number ) ) diff --git a/spec/models/automated_checks/claim_verifiers/employment_spec.rb b/spec/models/automated_checks/claim_verifiers/employment_spec.rb index facbf0ce9b..1f428b900e 100644 --- a/spec/models/automated_checks/claim_verifiers/employment_spec.rb +++ b/spec/models/automated_checks/claim_verifiers/employment_spec.rb @@ -24,7 +24,6 @@ module ClaimVerifiers national_insurance_number: "RT901113D", reference: "QKCVAQ3K", surname: "Bonnet-Fontaine", - teacher_reference_number: teacher_reference_number, policy: policy, submitted_at: DateTime.new(2022, 1, 12, 13, 0, 0) ) @@ -33,7 +32,8 @@ module ClaimVerifiers attributes_for( :"#{policy_underscored}_eligibility", :eligible, - current_school_id: school.id + current_school_id: school.id, + teacher_reference_number: teacher_reference_number ) ) diff --git a/spec/models/automated_checks/claim_verifiers/identity_spec.rb b/spec/models/automated_checks/claim_verifiers/identity_spec.rb index 4a7e6df081..b5e18c3aa4 100644 --- a/spec/models/automated_checks/claim_verifiers/identity_spec.rb +++ b/spec/models/automated_checks/claim_verifiers/identity_spec.rb @@ -17,7 +17,7 @@ module ClaimVerifiers end stub_qualified_teaching_statuses_show( - trn: claim_arg.teacher_reference_number, + trn: claim_arg.eligibility.teacher_reference_number, params: { birthdate: claim_arg.date_of_birth&.to_s, nino: claim_arg.national_insurance_number @@ -36,7 +36,6 @@ module ClaimVerifiers national_insurance_number: "QQ100000C", reference: "AB123456", surname: "ELIGIBLE", - teacher_reference_number: "1234567", policy: policy ) @@ -45,7 +44,8 @@ module ClaimVerifiers claim.eligibility.update!( attributes_for( :"#{policy_underscored}_eligibility", - :eligible + :eligible, + teacher_reference_number: "1234567" ) ) @@ -56,7 +56,7 @@ module ClaimVerifiers { claim: claim_arg, dqt_teacher_status: Dqt::Client.new.teacher.find( - claim_arg.teacher_reference_number, + claim_arg.eligibility.teacher_reference_number, birthdate: claim_arg.date_of_birth, nino: claim_arg.national_insurance_number ) @@ -79,7 +79,7 @@ module ClaimVerifiers dob: claim_arg.date_of_birth, name: claim_arg.full_name, nino: claim_arg.national_insurance_number, - trn: claim_arg.teacher_reference_number + trn: claim_arg.eligibility.teacher_reference_number } end @@ -554,7 +554,7 @@ module ClaimVerifiers reference: "AB123456", surname: "ELIGIBLE", tasks: [build(:task, name: :identity_confirmation)], - teacher_reference_number: "1234567" + eligibility_attributes: {teacher_reference_number: "1234567"} ) end @@ -675,7 +675,6 @@ module ClaimVerifiers national_insurance_number: " QQ100000C ", reference: "AB123456", surname: "ELIGIBLE ", - teacher_reference_number: " 1234567 ", policy: policy ) @@ -684,7 +683,8 @@ module ClaimVerifiers claim.eligibility.update!( attributes_for( :"#{policy_underscored}_eligibility", - :eligible + :eligible, + teacher_reference_number: " 1234567 " ) ) diff --git a/spec/models/automated_checks/claim_verifiers/induction_spec.rb b/spec/models/automated_checks/claim_verifiers/induction_spec.rb index 9a2f081ed0..7edd71f081 100644 --- a/spec/models/automated_checks/claim_verifiers/induction_spec.rb +++ b/spec/models/automated_checks/claim_verifiers/induction_spec.rb @@ -9,7 +9,7 @@ module ClaimVerifiers { claim: claim_arg, dqt_teacher_status: Dqt::Client.new.teacher.find( - claim_arg.teacher_reference_number, + claim_arg.eligibility.teacher_reference_number, birthdate: claim_arg.date_of_birth, nino: claim_arg.national_insurance_number ) @@ -30,7 +30,7 @@ module ClaimVerifiers end stub_qualified_teaching_statuses_show( - trn: claim_arg.teacher_reference_number, + trn: claim_arg.eligibility.teacher_reference_number, params: { birthdate: claim_arg.date_of_birth&.to_s, nino: claim_arg.national_insurance_number diff --git a/spec/models/automated_checks/claim_verifiers/qualifications_spec.rb b/spec/models/automated_checks/claim_verifiers/qualifications_spec.rb index e6287827ac..087ea5f231 100644 --- a/spec/models/automated_checks/claim_verifiers/qualifications_spec.rb +++ b/spec/models/automated_checks/claim_verifiers/qualifications_spec.rb @@ -17,7 +17,7 @@ module ClaimVerifiers end stub_qualified_teaching_statuses_show( - trn: claim_arg.teacher_reference_number, + trn: claim_arg.eligibility.teacher_reference_number, params: { birthdate: claim_arg.date_of_birth&.to_s, nino: claim_arg.national_insurance_number @@ -38,7 +38,6 @@ module ClaimVerifiers national_insurance_number: "QQ100000C", reference: "AB123456", surname: "ELIGIBLE", - teacher_reference_number: "1234567", policy: Policies::EarlyCareerPayments ) @@ -46,7 +45,8 @@ module ClaimVerifiers attributes_for( :early_career_payments_eligibility, :eligible, - qualification: :undergraduate_itt + qualification: :undergraduate_itt, + teacher_reference_number: "1234567" ) ) @@ -57,7 +57,7 @@ module ClaimVerifiers { claim: claim_arg, dqt_teacher_status: Dqt::Client.new.teacher.find( - claim_arg.teacher_reference_number, + claim_arg.eligibility.teacher_reference_number, birthdate: claim_arg.date_of_birth, nino: claim_arg.national_insurance_number ) @@ -331,7 +331,7 @@ module ClaimVerifiers reference: "AB123456", surname: "ELIGIBLE", tasks: [build(:task, name: :qualifications)], - teacher_reference_number: "1234567" + eligibility_attributes: {teacher_reference_number: "1234567"} ) end diff --git a/spec/models/claim/claims_preventing_payment_finder_spec.rb b/spec/models/claim/claims_preventing_payment_finder_spec.rb index 1af1abfd4e..5311772fdc 100644 --- a/spec/models/claim/claims_preventing_payment_finder_spec.rb +++ b/spec/models/claim/claims_preventing_payment_finder_spec.rb @@ -8,10 +8,10 @@ describe "#claims_preventing_payment" do let(:personal_details) do { - teacher_reference_number: generate(:teacher_reference_number), bank_account_number: "32828838", bank_sort_code: "183828", - first_name: "Boris" + first_name: "Boris", + eligibility_attributes: {teacher_reference_number: generate(:teacher_reference_number)} } end let(:claim) { create(:claim, :submitted, personal_details) } @@ -42,7 +42,9 @@ end it "includes the other claim where a topup is payrollable" do - lup_eligibility = create(:levelling_up_premium_payments_eligibility, :eligible, award_amount: 1500.0) + eligibility_attributes = inconsistent_personal_details.delete(:eligibility_attributes) + + lup_eligibility = create(:levelling_up_premium_payments_eligibility, :eligible, award_amount: 1500.0, **eligibility_attributes) other_claim = create(:claim, :approved, inconsistent_personal_details.merge(policy: Policies::LevellingUpPremiumPayments, eligibility: lup_eligibility)) create(:payment, claims: [other_claim]) other_claim.topups.create(award_amount: "500.00", created_by: user) diff --git a/spec/models/claim/data_report_request_spec.rb b/spec/models/claim/data_report_request_spec.rb index e61f14e5fa..d65834550a 100644 --- a/spec/models/claim/data_report_request_spec.rb +++ b/spec/models/claim/data_report_request_spec.rb @@ -21,7 +21,7 @@ it "contains the correct values" do claims.each_with_index do |claim, index| expect(report_request_csv[index].fields("Claim reference")).to include(claim.reference) - expect(report_request_csv[index].fields("Teacher reference number")).to include(claim.teacher_reference_number) + expect(report_request_csv[index].fields("Teacher reference number")).to include(claim.eligibility.teacher_reference_number) expect(report_request_csv[index].fields("NINO")).to include(claim.national_insurance_number) expect(report_request_csv[index].fields("Full name")).to include(claim.full_name) expect(report_request_csv[index].fields("Email")).to include(claim.email_address) @@ -54,7 +54,7 @@ it "contains the correct values" do claims.each_with_index do |claim, index| expect(report_request_csv[index].fields("Claim reference")).to include(claim.reference) - expect(report_request_csv[index].fields("Teacher reference number")).to include(claim.teacher_reference_number) + expect(report_request_csv[index].fields("Teacher reference number")).to include(claim.eligibility.teacher_reference_number) expect(report_request_csv[index].fields("NINO")).to include(claim.national_insurance_number) expect(report_request_csv[index].fields("Full name")).to include(claim.full_name) expect(report_request_csv[index].fields("Email")).to include(claim.email_address) diff --git a/spec/models/claim/matching_attribute_finder_spec.rb b/spec/models/claim/matching_attribute_finder_spec.rb index e2b67f5d6f..c1e868a0dd 100644 --- a/spec/models/claim/matching_attribute_finder_spec.rb +++ b/spec/models/claim/matching_attribute_finder_spec.rb @@ -4,40 +4,40 @@ describe "#matching_claims for ECP/LUP claims" do let!(:source_claim) { create(:claim, - teacher_reference_number: "0902344", national_insurance_number: "QQ891011C", email_address: "genghis.khan@mongol-empire.com", bank_account_number: "34682151", bank_sort_code: "972654", academic_year: AcademicYear.new("2019"), building_society_roll_number: "123456789/ABCD", - policy: Policies::EarlyCareerPayments) + policy: Policies::EarlyCareerPayments, + eligibility_attributes: {teacher_reference_number: "0902344"}) } let!(:student_loans_claim) { create(:claim, :submitted, - teacher_reference_number: "0902344", national_insurance_number: "QQ891011C", email_address: "genghis.khan@mongol-empire.com", bank_account_number: "34682151", bank_sort_code: "972654", academic_year: AcademicYear.new("2019"), building_society_roll_number: "123456789/ABCD", - policy: Policies::StudentLoans) + policy: Policies::StudentLoans, + eligibility_attributes: {teacher_reference_number: "0902344"}) } let!(:lup_claim) { create(:claim, :submitted, - teacher_reference_number: "0902344", national_insurance_number: "QQ891011C", email_address: "genghis.khan@mongol-empire.com", bank_account_number: "34682151", bank_sort_code: "972654", academic_year: AcademicYear.new("2019"), building_society_roll_number: "123456789/ABCD", - policy: Policies::LevellingUpPremiumPayments) + policy: Policies::LevellingUpPremiumPayments, + eligibility_attributes: {teacher_reference_number: "0902344"}) } subject(:matching_claims) { Claim::MatchingAttributeFinder.new(source_claim).matching_claims } @@ -50,14 +50,14 @@ describe "#matching_claims" do let(:source_claim) { create(:claim, - teacher_reference_number: "0902344", national_insurance_number: "QQ891011C", email_address: "genghis.khan@mongol-empire.com", bank_account_number: "34682151", bank_sort_code: "972654", academic_year: AcademicYear.new("2019"), building_society_roll_number: "123456789/ABCD", - policy: Policies::StudentLoans) + policy: Policies::StudentLoans, + eligibility_attributes: {teacher_reference_number: "0902344"}) } subject(:matching_claims) { Claim::MatchingAttributeFinder.new(source_claim).matching_claims } @@ -73,20 +73,20 @@ end it "does not include unsubmitted claims with matching attributes" do - create(:claim, :submittable, teacher_reference_number: source_claim.teacher_reference_number) + create(:claim, :submittable, eligibility_attributes: {teacher_reference_number: source_claim.eligibility.teacher_reference_number}) expect(matching_claims).to be_empty end it "does not include claims that match, but have a different policy" do - student_loans_claim = create(:claim, :submitted, teacher_reference_number: source_claim.teacher_reference_number, policy: Policies::StudentLoans) + student_loans_claim = create(:claim, :submitted, eligibility_attributes: {teacher_reference_number: source_claim.eligibility.teacher_reference_number}, policy: Policies::StudentLoans) expect(matching_claims).to contain_exactly(student_loans_claim) end it "does not include claims that match, but have a different academic year" do create(:claim, :submitted, - teacher_reference_number: source_claim.teacher_reference_number, + eligibility_attributes: {teacher_reference_number: source_claim.eligibility.teacher_reference_number}, academic_year: AcademicYear.new("2020"), policy: source_claim.policy) @@ -94,7 +94,7 @@ end it "includes a claim with a matching teacher reference number" do - claim_with_matching_attribute = create(:claim, :submitted, teacher_reference_number: source_claim.teacher_reference_number) + claim_with_matching_attribute = create(:claim, :submitted, eligibility_attributes: {teacher_reference_number: source_claim.eligibility.teacher_reference_number}) expect(matching_claims).to eq([claim_with_matching_attribute]) end diff --git a/spec/models/claim/personal_data_scrubber_spec.rb b/spec/models/claim/personal_data_scrubber_spec.rb index 10e8359a40..88e72b4511 100644 --- a/spec/models/claim/personal_data_scrubber_spec.rb +++ b/spec/models/claim/personal_data_scrubber_spec.rb @@ -181,7 +181,7 @@ travel_to last_academic_year - 1.week do claim = create(:claim, :submitted) amendment = create(:amendment, claim: claim, claim_changes: { - "teacher_reference_number" => [generate(:teacher_reference_number).to_s, claim.teacher_reference_number], + "teacher_reference_number" => [generate(:teacher_reference_number).to_s, claim.eligibility.teacher_reference_number], "payroll_gender" => ["male", claim.payroll_gender], "date_of_birth" => [25.years.ago.to_date, claim.date_of_birth], "student_loan_plan" => ["plan_1", claim.student_loan_plan], diff --git a/spec/models/claim/search_spec.rb b/spec/models/claim/search_spec.rb index 82a024c346..65c569a417 100644 --- a/spec/models/claim/search_spec.rb +++ b/spec/models/claim/search_spec.rb @@ -94,7 +94,7 @@ end context "search by teacher reference number" do - let(:claim) { create(:claim, :submitted, teacher_reference_number: teacher_reference_number) } + let!(:claim) { create(:claim, :submitted, eligibility_attributes: {teacher_reference_number: teacher_reference_number}) } context "matches" do let(:query) { teacher_reference_number } @@ -109,7 +109,7 @@ end context "multiple matches" do - let(:historical_matching_claim) { create(:claim, :submitted, teacher_reference_number: teacher_reference_number) } + let!(:historical_matching_claim) { create(:claim, :submitted, eligibility_attributes: {teacher_reference_number: teacher_reference_number}) } let(:query) { teacher_reference_number } specify { expect(search.claims).to contain_exactly(claim, historical_matching_claim) } diff --git a/spec/models/claim_auto_approval_spec.rb b/spec/models/claim_auto_approval_spec.rb index f394da79f4..b7b75d9a95 100644 --- a/spec/models/claim_auto_approval_spec.rb +++ b/spec/models/claim_auto_approval_spec.rb @@ -29,7 +29,7 @@ context "when the claim is a duplicate" do let(:claim) { create(:claim, :submitted) } - let!(:duplicate) { create(:claim, :submitted, teacher_reference_number: claim.teacher_reference_number, policy: claim.policy) } + let!(:duplicate) { create(:claim, :submitted, eligibility_attributes: {teacher_reference_number: claim.eligibility.teacher_reference_number}, policy: claim.policy) } it { is_expected.to eq(false) } end diff --git a/spec/models/claim_checking_tasks_spec.rb b/spec/models/claim_checking_tasks_spec.rb index d39e04ea4c..cdd181bded 100644 --- a/spec/models/claim_checking_tasks_spec.rb +++ b/spec/models/claim_checking_tasks_spec.rb @@ -29,7 +29,7 @@ shared_examples :matching_details_task do it "includes a task for matching details when there are claims with matching details" do - create(:claim, :submitted, policy:, teacher_reference_number: claim.teacher_reference_number) + create(:claim, :submitted, policy:, eligibility_attributes: {teacher_reference_number: claim.eligibility.teacher_reference_number}) expect(checking_tasks.applicable_task_names).to match_array(applicable_tasks + %w[matching_details]) end @@ -135,7 +135,7 @@ end end - let!(:previous_claim) { create(:claim, :submitted, policy:, teacher_reference_number: claim.teacher_reference_number) } + let!(:previous_claim) { create(:claim, :submitted, policy:, eligibility_attributes: {teacher_reference_number: claim.eligibility.teacher_reference_number}) } it { is_expected.to eq(false) } end diff --git a/spec/models/claim_spec.rb b/spec/models/claim_spec.rb index a30f2c380d..ef5c807cab 100644 --- a/spec/models/claim_spec.rb +++ b/spec/models/claim_spec.rb @@ -43,9 +43,9 @@ context "that has a teacher_reference_number" do it "validates the length of the teacher reference number" do - expect(build(:claim, teacher_reference_number: "1/2/3/4/5/6/7")).to be_valid - expect(build(:claim, teacher_reference_number: "1/2/3/4/5")).not_to be_valid - expect(build(:claim, teacher_reference_number: "12/345678")).not_to be_valid + expect(build(:claim, eligibility_attributes: {teacher_reference_number: "1/2/3/4/5/6/7"}).eligibility).to be_valid + expect(build(:claim, eligibility_attributes: {teacher_reference_number: "1/2/3/4/5"}).eligibility).not_to be_valid + expect(build(:claim, eligibility_attributes: {teacher_reference_number: "12/345678"}).eligibility).not_to be_valid end end @@ -109,20 +109,20 @@ end describe "#teacher_reference_number" do - let(:claim) { build(:claim, teacher_reference_number: teacher_reference_number) } + let(:claim) { build(:claim, eligibility_attributes: {teacher_reference_number: teacher_reference_number}) } context "when the teacher reference number is stored and contains non digits" do let(:teacher_reference_number) { "12\\23 /232 " } it "strips out the non digits" do claim.save! - expect(claim.teacher_reference_number).to eql("1223232") + expect(claim.eligibility.teacher_reference_number).to eql("1223232") end end context "before the teacher reference number is stored" do let(:teacher_reference_number) { "12/34567" } it "is not modified" do - expect(claim.teacher_reference_number).to eql("12/34567") + expect(claim.eligibility.teacher_reference_number).to eql("12/34567") end end end @@ -328,9 +328,9 @@ it "returns false when there exists another payrollable claim with the same teacher reference number but with inconsistent attributes that would prevent us from running payroll" do teacher_reference_number = generate(:teacher_reference_number) - create(:claim, :approved, teacher_reference_number: teacher_reference_number, date_of_birth: 20.years.ago) + create(:claim, :approved, eligibility_attributes: {teacher_reference_number: teacher_reference_number}, date_of_birth: 20.years.ago) - expect(create(:claim, :submitted, teacher_reference_number: teacher_reference_number, date_of_birth: 30.years.ago).approvable?).to eq false + expect(create(:claim, :submitted, eligibility_attributes: {teacher_reference_number: teacher_reference_number}, date_of_birth: 30.years.ago).approvable?).to eq false end context "when the claim is held" do @@ -572,7 +572,6 @@ :address_line_4, :postcode, :payroll_gender, - :teacher_reference_number, :national_insurance_number, :email_address, :mobile_number, @@ -592,7 +591,8 @@ :details_check, :email_address_check, :mobile_check, - :qualifications_details_check + :qualifications_details_check, + :column_to_remove_teacher_reference_number ]) end end diff --git a/spec/models/decision_spec.rb b/spec/models/decision_spec.rb index fb6e7ad41b..24adf8c05b 100644 --- a/spec/models/decision_spec.rb +++ b/spec/models/decision_spec.rb @@ -71,7 +71,7 @@ it "prevents a claim with matching bank details from being approved" do personal_details = { - teacher_reference_number: generate(:teacher_reference_number), + eligibility_attributes: {teacher_reference_number: generate(:teacher_reference_number)}, bank_sort_code: "112233" } diff --git a/spec/models/early_career_payments/eligibility_spec.rb b/spec/models/early_career_payments/eligibility_spec.rb index 1fc2dd4073..c4e7f008a3 100644 --- a/spec/models/early_career_payments/eligibility_spec.rb +++ b/spec/models/early_career_payments/eligibility_spec.rb @@ -117,9 +117,9 @@ end it "validates that the award_amount is less than £7,500 when amending a claim" do - expect(Policies::EarlyCareerPayments::Eligibility.new(award_amount: 7_501)).not_to be_valid(:amendment) - expect(Policies::EarlyCareerPayments::Eligibility.new(award_amount: 7_500)).to be_valid(:amendment) - expect(Policies::EarlyCareerPayments::Eligibility.new(award_amount: 7_499)).to be_valid(:amendment) + expect(Policies::EarlyCareerPayments::Eligibility.new(teacher_reference_number: "1234567", award_amount: 7_501)).not_to be_valid(:amendment) + expect(Policies::EarlyCareerPayments::Eligibility.new(teacher_reference_number: "1234567", award_amount: 7_500)).to be_valid(:amendment) + expect(Policies::EarlyCareerPayments::Eligibility.new(teacher_reference_number: "1234567", award_amount: 7_499)).to be_valid(:amendment) end end end diff --git a/spec/models/payment_spec.rb b/spec/models/payment_spec.rb index dc2d64a64c..eedf7abd15 100644 --- a/spec/models/payment_spec.rb +++ b/spec/models/payment_spec.rb @@ -71,7 +71,7 @@ let(:claims) do build_list(:claim, 2, :approved, national_insurance_number: "JM603818B", - teacher_reference_number: "1234567", + eligibility_attributes: {teacher_reference_number: "1234567"}, email_address: "email@example.com", bank_sort_code: "112233", bank_account_number: "95928482", @@ -97,7 +97,7 @@ end it "is invalid when claims' teacher reference numbers do not match" do - claims[0].teacher_reference_number = "9988776" + claims[0].eligibility.teacher_reference_number = "9988776" expect(subject).not_to be_valid expect(subject.errors[:claims]).to eq(["#{claims[0].reference} and #{claims[1].reference} have different values for teacher reference number"]) @@ -179,7 +179,7 @@ let(:claims) do personal_details = { national_insurance_number: "JM603818B", - teacher_reference_number: "1234567", + eligibility_attributes: {teacher_reference_number: "1234567"}, bank_sort_code: "112233", bank_account_number: "95928482", building_society_roll_number: nil @@ -201,7 +201,7 @@ let(:personal_details) do { national_insurance_number: generate(:national_insurance_number), - teacher_reference_number: generate(:teacher_reference_number), + eligibility_attributes: {teacher_reference_number: generate(:teacher_reference_number)}, email_address: generate(:email_address), bank_sort_code: "112233", bank_account_number: "95928482", @@ -262,11 +262,11 @@ end describe "method delegations" do - described_class::PERSONAL_DETAILS_ATTRIBUTES_PERMITTING_DISCREPANCIES.each do |method| + described_class::PERSONAL_CLAIM_DETAILS_ATTRIBUTES_PERMITTING_DISCREPANCIES.each do |method| it { is_expected.to delegate_method(method).to(:claim_for_personal_details) } end - described_class::PERSONAL_DETAILS_ATTRIBUTES_FORBIDDING_DISCREPANCIES.each do |method| + described_class::PERSONAL_CLAIM_DETAILS_ATTRIBUTES_FORBIDDING_DISCREPANCIES.each do |method| it { is_expected.to delegate_method(method).to(:claim_for_personal_details) } end end diff --git a/spec/models/payroll/payment_csv_row_spec.rb b/spec/models/payroll/payment_csv_row_spec.rb index 851514f27b..e306b8356e 100644 --- a/spec/models/payroll/payment_csv_row_spec.rb +++ b/spec/models/payroll/payment_csv_row_spec.rb @@ -16,7 +16,7 @@ let(:personal_details_for_student_loans_and_early_career_payments_claim) do { national_insurance_number: generate(:national_insurance_number), - teacher_reference_number: generate(:teacher_reference_number), + eligibility_attributes: {teacher_reference_number: generate(:teacher_reference_number)}, payroll_gender: :female, date_of_birth: Date.new(1980, 12, 1), student_loan_plan: StudentLoan::PLAN_2, @@ -105,7 +105,7 @@ let(:personal_details_for_ecp_claim_1) do { national_insurance_number: generate(:national_insurance_number), - teacher_reference_number: generate(:teacher_reference_number), + eligibility_attributes: {teacher_reference_number: generate(:teacher_reference_number)}, payroll_gender: :male, date_of_birth: Date.new(1988, 3, 21), student_loan_plan: StudentLoan::PLAN_1_AND_3, @@ -177,7 +177,7 @@ let(:personal_details_for_ecp_claim_2) do { national_insurance_number: generate(:national_insurance_number), - teacher_reference_number: generate(:teacher_reference_number), + eligibility_attributes: {teacher_reference_number: generate(:teacher_reference_number)}, payroll_gender: :female, date_of_birth: Date.new(1994, 6, 30), student_loan_plan: StudentLoan::PLAN_1, diff --git a/spec/models/payroll_run_spec.rb b/spec/models/payroll_run_spec.rb index a353d9c842..ac6d7dd487 100644 --- a/spec/models/payroll_run_spec.rb +++ b/spec/models/payroll_run_spec.rb @@ -54,8 +54,8 @@ describe "#total_award_amount" do it "returns the sum of the award amounts of its claims" do - payment_1 = build(:payment, claims: [build(:claim, :approved, eligibility: build(:student_loans_eligibility, :eligible, student_loan_repayment_amount: 1500))]) - payment_2 = build(:payment, claims: [build(:claim, :approved, eligibility: build(:student_loans_eligibility, :eligible, student_loan_repayment_amount: 2000))]) + payment_1 = build(:payment, claims: [build(:claim, :approved, eligibility_attributes: {student_loan_repayment_amount: 1500})]) + payment_2 = build(:payment, claims: [build(:claim, :approved, eligibility_attributes: {student_loan_repayment_amount: 2000})]) payroll_run = PayrollRun.create!(created_by: user, payments: [payment_1, payment_2]) @@ -66,13 +66,13 @@ describe "#number_of_claims_for_policy" do it "returns the correct number of claims under each policy" do payment_1 = build(:payment, claims: [ - build(:claim, :approved, eligibility: build(:student_loans_eligibility, :eligible, student_loan_repayment_amount: 1500)) + build(:claim, :approved, eligibility_attributes: {student_loan_repayment_amount: 1500}) ]) payment_2 = build(:payment, claims: [ - build(:claim, :approved, policy: Policies::EarlyCareerPayments, eligibility: build(:early_career_payments_eligibility, :eligible)) + build(:claim, :approved, policy: Policies::EarlyCareerPayments) ]) payment_3 = build(:payment, claims: [ - build(:claim, :approved, policy: Policies::LevellingUpPremiumPayments, eligibility: build(:levelling_up_premium_payments_eligibility, :eligible)) + build(:claim, :approved, policy: Policies::LevellingUpPremiumPayments) ]) payroll_run = PayrollRun.create!(created_by: user, payments: [payment_1, payment_2, payment_3]) @@ -86,20 +86,20 @@ describe "#total_claim_amount_for_policy" do it "returns the correct total amount claimed under each policy" do payment_1 = build(:payment, claims: [ - build(:claim, :approved, eligibility: build(:student_loans_eligibility, :eligible, student_loan_repayment_amount: 1500)) + build(:claim, :approved, policy: Policies::StudentLoans, eligibility_attributes: {student_loan_repayment_amount: 1500}) ]) payment_2 = build(:payment, claims: [ - build(:claim, :approved, policy: Policies::EarlyCareerPayments, eligibility: build(:early_career_payments_eligibility, :eligible)) + build(:claim, :approved, policy: Policies::EarlyCareerPayments) ]) payment_3 = build(:payment, claims: [ - build(:claim, :approved, policy: Policies::EarlyCareerPayments, eligibility: build(:early_career_payments_eligibility, :eligible)) + build(:claim, :approved, policy: Policies::EarlyCareerPayments) ]) payment_4 = build(:payment, claims: [ - build(:claim, :approved, eligibility: build(:student_loans_eligibility, :eligible, student_loan_repayment_amount: 1000)) + build(:claim, :approved, eligibility_attributes: {student_loan_repayment_amount: 1000}) ]) payment_5 = build(:payment, claims: [ - build(:claim, :approved, policy: Policies::LevellingUpPremiumPayments, teacher_reference_number: "1234567", bank_sort_code: "123456", bank_account_number: "12345678", eligibility: build(:levelling_up_premium_payments_eligibility, :eligible)), - build(:claim, :approved, teacher_reference_number: "1234567", bank_sort_code: "123456", bank_account_number: "12345678", eligibility: build(:student_loans_eligibility, :eligible, student_loan_repayment_amount: 1000)) + build(:claim, :approved, policy: Policies::LevellingUpPremiumPayments, bank_sort_code: "123456", bank_account_number: "12345678", eligibility_attributes: {teacher_reference_number: "1234567"}), + build(:claim, :approved, bank_sort_code: "123456", bank_account_number: "12345678", eligibility_attributes: {student_loan_repayment_amount: 1000, teacher_reference_number: "1234567"}) ]) payroll_run = PayrollRun.create!(created_by: user, payments: [payment_1, payment_2, payment_3, payment_4, payment_5]) @@ -126,7 +126,7 @@ let(:personal_details) do { national_insurance_number: generate(:national_insurance_number), - teacher_reference_number: generate(:teacher_reference_number), + eligibility_attributes: {teacher_reference_number: generate(:teacher_reference_number)}, email_address: generate(:email_address), bank_sort_code: "112233", bank_account_number: "95928482", diff --git a/spec/models/policies_spec.rb b/spec/models/policies_spec.rb index 89d90aff26..9384573a53 100644 --- a/spec/models/policies_spec.rb +++ b/spec/models/policies_spec.rb @@ -13,8 +13,8 @@ describe "::AMENDABLE_ELIGIBILITY_ATTRIBUTES" do it do - expect(described_class::AMENDABLE_ELIGIBILITY_ATTRIBUTES).to eq([ - :student_loan_repayment_amount, :award_amount, :award_amount + expect(described_class::AMENDABLE_ELIGIBILITY_ATTRIBUTES.sort).to eq([ + :award_amount, :student_loan_repayment_amount, :teacher_reference_number ]) end end diff --git a/spec/models/student_loans/eligibility_spec.rb b/spec/models/student_loans/eligibility_spec.rb index c452cbd78a..9dc19a469b 100644 --- a/spec/models/student_loans/eligibility_spec.rb +++ b/spec/models/student_loans/eligibility_spec.rb @@ -50,8 +50,8 @@ end it "validates that the loan repayment less than £5000 when amending a claim" do - expect(described_class.new(student_loan_repayment_amount: "5001")).not_to be_valid(:amendment) - expect(described_class.new(student_loan_repayment_amount: "1200")).to be_valid(:amendment) + expect(described_class.new(teacher_reference_number: "1234567", student_loan_repayment_amount: "5001")).not_to be_valid(:amendment) + expect(described_class.new(teacher_reference_number: "1234567", student_loan_repayment_amount: "1200")).to be_valid(:amendment) end end diff --git a/spec/models/teachers_pensions_service_spec.rb b/spec/models/teachers_pensions_service_spec.rb index ca55cdf177..52621bae15 100644 --- a/spec/models/teachers_pensions_service_spec.rb +++ b/spec/models/teachers_pensions_service_spec.rb @@ -8,7 +8,7 @@ let(:school) { create(:school, local_authority:, establishment_number:) } let(:la_urn) { local_authority.code } let(:school_urn) { school.establishment_number } - let(:teacher_reference_number) { claim.teacher_reference_number } + let(:teacher_reference_number) { claim.eligibility.teacher_reference_number } let(:start_date) { end_date - 1.week } describe ".recent_tps_school" do @@ -63,7 +63,7 @@ let!(:ineligible_school) { create(:school, :student_loans_ineligible) } let!(:ineligible_school2) { create(:school, :student_loans_ineligible) } let(:trn) { "1234567" } - let(:claim) { create(:claim, teacher_reference_number: trn) } + let(:claim) { create(:claim, eligibility_attributes: {teacher_reference_number: trn}) } context "previous financial year has eligible school and ineligible school" do it "returns most recent eligible school" do diff --git a/spec/requests/admin_amendments_spec.rb b/spec/requests/admin_amendments_spec.rb index 6b4f07cf12..ac416edf14 100644 --- a/spec/requests/admin_amendments_spec.rb +++ b/spec/requests/admin_amendments_spec.rb @@ -1,13 +1,13 @@ require "rails_helper" RSpec.describe "Admin claim amendments" do - let(:claim) { create(:claim, :submitted, teacher_reference_number: "1234567", bank_sort_code: "010203", date_of_birth: 25.years.ago.to_date) } + let(:claim) { create(:claim, :submitted, eligibility_attributes: {teacher_reference_number: "1234567"}, bank_sort_code: "010203", date_of_birth: 25.years.ago.to_date) } context "when signed in as a service operator" do before { @signed_in_user = sign_in_as_service_operator } describe "admin/amendments#index" do - let(:claim) { create(:claim, :submitted, teacher_reference_number: "1234567") } + let(:claim) { create(:claim, :submitted, eligibility_attributes: {teacher_reference_number: "1234567"}) } let!(:amendment) { create(:amendment, claim: claim, notes: "Made a change", claim_changes: {"teacher_reference_number" => ["7654321", "1234567"]}) } it "list the amendments on a claim" do @@ -23,7 +23,7 @@ old_date_of_birth = claim.date_of_birth new_date_of_birth = 30.years.ago.to_date expect { - post admin_claim_amendments_url(claim, amendment: {claim: {teacher_reference_number: "7654321", bank_sort_code: "111213", "date_of_birth(3i)": new_date_of_birth.day, "date_of_birth(2i)": new_date_of_birth.month, "date_of_birth(1i)": new_date_of_birth.year}, + post admin_claim_amendments_url(claim, amendment: {claim: {eligibility_attributes: {teacher_reference_number: "7654321"}, bank_sort_code: "111213", "date_of_birth(3i)": new_date_of_birth.day, "date_of_birth(2i)": new_date_of_birth.month, "date_of_birth(1i)": new_date_of_birth.year}, notes: "Claimant made a typo"}) }.to change { claim.reload.amendments.size }.by(1) @@ -39,7 +39,7 @@ expect(amendment.notes).to eq("Claimant made a typo") expect(amendment.created_by).to eq(@signed_in_user) - expect(claim.teacher_reference_number).to eq("7654321") + expect(claim.eligibility.teacher_reference_number).to eq("7654321") expect(claim.bank_sort_code).to eq("111213") expect(claim.date_of_birth).to eq(new_date_of_birth) end @@ -66,9 +66,9 @@ it "displays a validation error and does not update the claim or create an amendment when invalid values are entered" do expect { - post admin_claim_amendments_url(claim, amendment: {claim: {teacher_reference_number: "654321", bank_account_number: ""}, + post admin_claim_amendments_url(claim, amendment: {claim: {eligibility_attributes: {teacher_reference_number: "654321"}, bank_account_number: ""}, notes: "Claimant made a typo"}) - }.not_to change { [claim.reload.teacher_reference_number, claim.amendments.size] } + }.not_to change { [claim.eligibility.reload.teacher_reference_number, claim.amendments.size] } expect(response).to have_http_status(:ok) @@ -78,9 +78,9 @@ it "displays an error message and does not create an amendment when none of the claim’s values are changed" do expect { - post admin_claim_amendments_url(claim, amendment: {claim: {teacher_reference_number: claim.teacher_reference_number}, + post admin_claim_amendments_url(claim, amendment: {claim: {eligibility_attributes: {teacher_reference_number: claim.eligibility.teacher_reference_number}}, notes: "Claimant made a typo"}) - }.not_to change { [claim.reload.teacher_reference_number, claim.amendments.size] } + }.not_to change { [claim.eligibility.reload.teacher_reference_number, claim.amendments.size] } expect(response).to have_http_status(:ok) @@ -105,7 +105,7 @@ let(:claim) { create(:claim, :approved, payments: [payment]) } it "shows an error" do - post admin_claim_amendments_url(claim, amendment: {claim: {teacher_reference_number: claim.teacher_reference_number}, + post admin_claim_amendments_url(claim, amendment: {claim: {eligibility_attributes: {teacher_reference_number: claim.eligibility.teacher_reference_number}}, notes: "Claimant made a typo"}) expect(response.body).to include("This claim cannot be amended.") end @@ -130,8 +130,8 @@ describe "admin_amendments#create" do it "returns a unauthorized response and does not create an amendment or change the claim" do expect { - post admin_claim_amendments_url(claim, amendment: {claim: {teacher_reference_number: "7654321"}}) - }.not_to change { [claim.reload.teacher_reference_number, claim.amendments.size] } + post admin_claim_amendments_url(claim, amendment: {claim: {eligibility_attributes: {teacher_reference_number: "7654321"}}}) + }.not_to change { [claim.eligibility.reload.teacher_reference_number, claim.amendments.size] } expect(response).to have_http_status(:unauthorized) end diff --git a/spec/requests/admin_claims_spec.rb b/spec/requests/admin_claims_spec.rb index ec6cb4b437..f7c6fce3de 100644 --- a/spec/requests/admin_claims_spec.rb +++ b/spec/requests/admin_claims_spec.rb @@ -110,7 +110,7 @@ end context "when another claim has matching attributes" do - let!(:claim_with_matching_attributes) { create(:claim, :submitted, teacher_reference_number: claim.teacher_reference_number, policy: policy) } + let!(:claim_with_matching_attributes) { create(:claim, :submitted, eligibility_attributes: {teacher_reference_number: claim.eligibility.teacher_reference_number}, policy: policy) } it "returns the claim and the duplicate" do get admin_claim_path(claim) diff --git a/spec/requests/admin_decisions_spec.rb b/spec/requests/admin_decisions_spec.rb index 50a45e594e..73d56b292e 100644 --- a/spec/requests/admin_decisions_spec.rb +++ b/spec/requests/admin_decisions_spec.rb @@ -219,7 +219,7 @@ let(:personal_details) do { national_insurance_number: generate(:national_insurance_number), - teacher_reference_number: generate(:teacher_reference_number), + eligibility_attributes: {teacher_reference_number: generate(:teacher_reference_number)}, date_of_birth: 30.years.ago.to_date, student_loan_plan: StudentLoan::PLAN_1, email_address: "email@example.com", diff --git a/spec/requests/admin_payroll_runs_spec.rb b/spec/requests/admin_payroll_runs_spec.rb index 7f2dd0f036..ba603a0af4 100644 --- a/spec/requests/admin_payroll_runs_spec.rb +++ b/spec/requests/admin_payroll_runs_spec.rb @@ -17,9 +17,9 @@ it "limits the number of claims entering payroll when exceeding the maximum allowed" do stubbed_max_payments = stub_const("PayrollRun::MAX_MONTHLY_PAYMENTS", 2) - create(:claim, :approved, eligibility: create(:student_loans_eligibility, student_loan_repayment_amount: 100), submitted_at: 3.days.ago) - create(:claim, :approved, eligibility: create(:student_loans_eligibility, student_loan_repayment_amount: 50), submitted_at: 1.days.ago) - create(:claim, :approved, eligibility: create(:student_loans_eligibility, student_loan_repayment_amount: 10), submitted_at: 2.days.ago) + create(:claim, :approved, eligibility_attributes: {student_loan_repayment_amount: 100}, submitted_at: 3.days.ago) + create(:claim, :approved, eligibility_attributes: {student_loan_repayment_amount: 50}, submitted_at: 1.days.ago) + create(:claim, :approved, eligibility_attributes: {student_loan_repayment_amount: 10}, submitted_at: 2.days.ago) get new_admin_payroll_run_path diff --git a/spec/requests/admin_tps_data_upload_spec.rb b/spec/requests/admin_tps_data_upload_spec.rb index eb92da3f7f..56d49ded09 100644 --- a/spec/requests/admin_tps_data_upload_spec.rb +++ b/spec/requests/admin_tps_data_upload_spec.rb @@ -76,10 +76,10 @@ def upload_tps_data_csm_file(file) :claim, :submitted, policy: Policies::EarlyCareerPayments, - teacher_reference_number: 1000106, submitted_at: Date.new(2022, 7, 15), academic_year: AcademicYear::Type.new.serialize(AcademicYear.new(2021)), eligibility_attributes: { + teacher_reference_number: 1000106, current_school: current_school } ) @@ -90,9 +90,9 @@ def upload_tps_data_csm_file(file) :claim, :submitted, policy: Policies::EarlyCareerPayments, - teacher_reference_number: 1000107, submitted_at: Date.new(2022, 7, 15), - academic_year: AcademicYear::Type.new.serialize(AcademicYear.new(2021)) + academic_year: AcademicYear::Type.new.serialize(AcademicYear.new(2021)), + eligibility_attributes: {teacher_reference_number: 1000107} ) end @@ -101,9 +101,9 @@ def upload_tps_data_csm_file(file) :claim, :submitted, policy: Policies::EarlyCareerPayments, - teacher_reference_number: 1000108, submitted_at: Date.new(2022, 7, 15), - academic_year: AcademicYear::Type.new.serialize(AcademicYear.new(2021)) + academic_year: AcademicYear::Type.new.serialize(AcademicYear.new(2021)), + eligibility_attributes: {teacher_reference_number: 1000108} ) end @@ -143,7 +143,7 @@ def upload_tps_data_csm_file(file) it "runs the employment task again for NO MATCH claims" do csv = <<~CSV Teacher reference number,NINO,Start Date,End Date,LA URN,School URN,Employer ID - #{claim_no_data.teacher_reference_number},ZX043155C,01/07/2022,30/09/2022,#{claim_no_data.school.local_authority.code},#{claim_no_data.school.establishment_number},1122 + #{claim_no_data.eligibility.teacher_reference_number},ZX043155C,01/07/2022,30/09/2022,#{claim_no_data.school.local_authority.code},#{claim_no_data.school.establishment_number},1122 CSV file = Rack::Test::UploadedFile.new(StringIO.new(csv), "text/csv", original_filename: "tps_data.csv") @@ -184,10 +184,10 @@ def upload_tps_data_csm_file(file) :claim, :submitted, policy: Policies::StudentLoans, - teacher_reference_number: 1000106, submitted_at: Date.new(2022, 7, 15), academic_year: AcademicYear::Type.new.serialize(AcademicYear.new(2021)), eligibility_attributes: { + teacher_reference_number: 1000106, current_school: current_school, claim_school: claim_school } @@ -199,9 +199,9 @@ def upload_tps_data_csm_file(file) :claim, :submitted, policy: Policies::StudentLoans, - teacher_reference_number: 1000107, submitted_at: Date.new(2022, 7, 15), - academic_year: AcademicYear::Type.new.serialize(AcademicYear.new(2021)) + academic_year: AcademicYear::Type.new.serialize(AcademicYear.new(2021)), + eligibility_attributes: {teacher_reference_number: 1000107} ) end diff --git a/spec/support/admin_edit_claim_feature_shared_examples.rb b/spec/support/admin_edit_claim_feature_shared_examples.rb index 6494e83ed9..555602db1d 100644 --- a/spec/support/admin_edit_claim_feature_shared_examples.rb +++ b/spec/support/admin_edit_claim_feature_shared_examples.rb @@ -30,7 +30,7 @@ end context "non-claim attribute" do - let(:old_value) { claim.teacher_reference_number } + let(:old_value) { claim.eligibility.teacher_reference_number } let(:new_value) { old_value.next } let(:reason) { "Fix typo" } diff --git a/spec/support/admin_view_claim_feature_shared_examples.rb b/spec/support/admin_view_claim_feature_shared_examples.rb index 6f02411e14..6a94d47da8 100644 --- a/spec/support/admin_view_claim_feature_shared_examples.rb +++ b/spec/support/admin_view_claim_feature_shared_examples.rb @@ -34,13 +34,12 @@ } let!(:similar_claim) { - eligibility = create(:"#{policy.to_s.underscore}_eligibility", :eligible) + eligibility = create(:"#{policy.to_s.underscore}_eligibility", :eligible, teacher_reference_number: multiple_claim.eligibility.teacher_reference_number) create( :claim, :submitted, policy: policy, - eligibility: eligibility, - teacher_reference_number: multiple_claim.teacher_reference_number + eligibility: eligibility ) } diff --git a/spec/support/fixture_helpers.rb b/spec/support/fixture_helpers.rb index f8213c56af..3203f4c8ce 100644 --- a/spec/support/fixture_helpers.rb +++ b/spec/support/fixture_helpers.rb @@ -13,7 +13,7 @@ def claim_from_example_dqt_report(trait) create(:claim, :submitted, first_name: "FRED", surname: "ELIGIBLE", - teacher_reference_number: "1234567", + eligibility_attributes: {teacher_reference_number: "1234567"}, reference: "AB123456", date_of_birth: Date.new(1990, 8, 23), national_insurance_number: "QQ123456C") @@ -23,7 +23,7 @@ def claim_from_example_dqt_report(trait) create(:claim, :submitted, first_name: "Dwayne", surname: "Hecos", - teacher_reference_number: "9876543", + eligibility_attributes: {teacher_reference_number: "9876543"}, reference: "ZY987654", date_of_birth: Date.new(1991, 1, 8), national_insurance_number: "QQ123456C") @@ -33,7 +33,7 @@ def claim_from_example_dqt_report(trait) create(:claim, :submitted, first_name: "Jo", surname: "Eligible", - teacher_reference_number: "8901231", + eligibility_attributes: {teacher_reference_number: "8901231"}, reference: "RR123456", date_of_birth: Date.new(1899, 1, 1), national_insurance_number: "QQ123456C") @@ -43,33 +43,33 @@ def claim_from_example_dqt_report(trait) create(:claim, :submitted, first_name: "Sarah", surname: "Eligible", - teacher_reference_number: "8981212", + eligibility_attributes: {teacher_reference_number: "8981212"}, reference: "DD123456", date_of_birth: Date.new(1980, 4, 10), national_insurance_number: "QQ123456C") when :claim_without_dqt_record # Submitted claim that has no DQT associated with it - create(:claim, :submitted, teacher_reference_number: "3456789", reference: "XX123456") + create(:claim, :submitted, eligibility_attributes: {teacher_reference_number: "3456789"}, reference: "XX123456") when :claim_with_ineligible_dqt_record # Submitted claim with matching data in DQT that is considered ineligible create(:claim, :submitted, - teacher_reference_number: "6758493", + eligibility_attributes: {teacher_reference_number: "6758493"}, reference: "CD123456", date_of_birth: Date.new(1979, 4, 21)) when :claim_with_decision # Eligible claim with matching data that already has a decision create(:claim, :approved, - teacher_reference_number: "5554433", + eligibility_attributes: {teacher_reference_number: "5554433"}, reference: "EF123456", date_of_birth: Date.new(1985, 5, 15)) when :claim_with_qualification_task # Eligible claim with matching data that already has a qualification task create(:claim, :submitted, - teacher_reference_number: "6060606", + eligibility_attributes: {teacher_reference_number: "6060606"}, reference: "GH123456", date_of_birth: Date.new(1980, 10, 4), tasks: [build(:task, name: "qualifications")]) From 34f61e10fb9e3d750909b407e4a71fcdbcb2a0c6 Mon Sep 17 00:00:00 2001 From: Kenneth Lee Date: Fri, 21 Jun 2024 14:49:27 +0100 Subject: [PATCH 17/66] Fix /address slug being considered incomplete * If the postcode search and address selected - /address is considered completed * Previous logic would redirect from gender slug to /address as it was "incomplete" * Because trn presence is non longer on the Claim, the claim is considered submittable on gender submit * This causes next_slug to be "check-your-answers" however "teacher-reference-number" is incomplete so redirects correctly --- app/models/journeys/page_sequence.rb | 20 +++++++++----------- 1 file changed, 9 insertions(+), 11 deletions(-) diff --git a/app/models/journeys/page_sequence.rb b/app/models/journeys/page_sequence.rb index 9997705587..930c2bcf29 100644 --- a/app/models/journeys/page_sequence.rb +++ b/app/models/journeys/page_sequence.rb @@ -3,7 +3,7 @@ # Used to model the sequence of pages that make up the claim process. module Journeys class PageSequence - attr_reader :current_slug, :completed_slugs + attr_reader :current_slug DEAD_END_SLUGS = %w[complete existing-session eligible-later future-eligibility ineligible] OPTIONAL_SLUGS = %w[postcode-search select-home-address reset-claim] @@ -26,7 +26,7 @@ def next_slug return "ineligible" if journey_ineligible? - if completed? + if claim_submittable? return "student-loan-amount" if updating_personal_details? && in_sequence?("student-loan-amount") return "check-your-answers" end @@ -47,10 +47,16 @@ def in_sequence?(slug) def has_completed_journey_until?(slug) return true if DEAD_END_SLUGS.include?(slug) - return true if (slug == "address" || answers.postcode.present?) && incomplete_slugs == ["address"] incomplete_slugs.empty? end + def completed_slugs + # /address is considered completed if provided via /postcode-search and /select-home-address + return @completed_slugs + ["address"] if answers.postcode.present? + + @completed_slugs + end + def next_required_slug (slugs - completed_slugs - OPTIONAL_SLUGS).first end @@ -119,13 +125,5 @@ def claim_submittable? def journey_ineligible? @journey_ineligible ||= journey::EligibilityChecker.new(journey_session: @journey_session).ineligible? end - - def completed? - if journey == Journeys::AdditionalPaymentsForTeaching - claim_submittable? && answers.teacher_reference_number.present? - else - claim_submittable? - end - end end end From e25c92f5716b2be98bb995fa7f3c3ad5463dd14e Mon Sep 17 00:00:00 2001 From: Kenneth Lee Date: Mon, 24 Jun 2024 19:32:22 +0100 Subject: [PATCH 18/66] ClaimsPreventingPaymentFinder - move config to Policy level * Guard against policies not configured and without a TRN --- app/models/base_policy.rb | 10 ++++++++++ .../claim/claims_preventing_payment_finder.rb | 16 ++++++++++------ app/models/policies/early_career_payments.rb | 7 +++++++ .../policies/levelling_up_premium_payments.rb | 7 +++++++ app/models/policies/student_loans.rb | 7 +++++++ 5 files changed, 41 insertions(+), 6 deletions(-) diff --git a/app/models/base_policy.rb b/app/models/base_policy.rb index 7ffd82daf1..f0a6810f36 100644 --- a/app/models/base_policy.rb +++ b/app/models/base_policy.rb @@ -24,4 +24,14 @@ def locale_key def payroll_file_name to_s end + + def policies_claimable + return [] unless self.const_defined?(:OTHER_CLAIMABLE_POLICIES) + + [self] + self::OTHER_CLAIMABLE_POLICIES + end + + def policy_eligibilities_claimable + policies_claimable.map { |p| p::Eligibility } + end end diff --git a/app/models/claim/claims_preventing_payment_finder.rb b/app/models/claim/claims_preventing_payment_finder.rb index 7646b94074..82be1248d9 100644 --- a/app/models/claim/claims_preventing_payment_finder.rb +++ b/app/models/claim/claims_preventing_payment_finder.rb @@ -15,6 +15,9 @@ def initialize(claim) # The returned claims have different payment or tax details to those # provided by `claim`, and hence `claim` cannot be paid in the same payment # as the returned claims. + # + # NOTE: This only works for ECP/LUPP and TSLR cross policy as this requires a TRN + # Driven by: Policies.policies_claimable(policy) using OTHER_CLAIMABLE_POLICIES config otherwise this just returns [] def claims_preventing_payment @claims_preventing_payment ||= find_claims_preventing_payment end @@ -22,16 +25,17 @@ def claims_preventing_payment private def find_claims_preventing_payment - eligibility_ids = [ - Policies::StudentLoans::Eligibility.where(teacher_reference_number: claim.eligibility.teacher_reference_number), - Policies::EarlyCareerPayments::Eligibility.where(teacher_reference_number: claim.eligibility.teacher_reference_number), - Policies::LevellingUpPremiumPayments::Eligibility.where(teacher_reference_number: claim.eligibility.teacher_reference_number) - ].flatten.map(&:id) + eligibility_ids = claim.policy.policies_claimable.map { |policy| + policy::Eligibility.where(teacher_reference_number: claim.eligibility.teacher_reference_number) + }.flatten.map(&:id) payrollable_claims_from_same_claimant = Claim.payrollable.where(eligibility_id: eligibility_ids) payrollable_topup_claims_from_same_claimant = Topup.includes(:claim).payrollable - .select { |t| t.claim.eligibility.teacher_reference_number == claim.eligibility.teacher_reference_number } + .select { |t| + claim.policy.policy_eligibilities_claimable.map(&:to_s).include?(t.claim.eligibility_type) && + t.claim.eligibility.teacher_reference_number == claim.eligibility.teacher_reference_number + } .map(&:claim) [payrollable_claims_from_same_claimant, payrollable_topup_claims_from_same_claimant].reduce([], :concat).select do |other_claim| diff --git a/app/models/policies/early_career_payments.rb b/app/models/policies/early_career_payments.rb index 4147b7bc82..94280c8da2 100644 --- a/app/models/policies/early_career_payments.rb +++ b/app/models/policies/early_career_payments.rb @@ -24,6 +24,13 @@ module EarlyCareerPayments POLICY_START_YEAR = AcademicYear.new(2021).freeze + # Used in + # - checking payments with multiple policies: ClaimsPreventingPaymentFinder + OTHER_CLAIMABLE_POLICIES = [ + LevellingUpPremiumPayments, + StudentLoans + ].freeze + def eligibility_page_url "https://www.gov.uk/guidance/early-career-payments-guidance-for-teachers-and-schools" end diff --git a/app/models/policies/levelling_up_premium_payments.rb b/app/models/policies/levelling_up_premium_payments.rb index b7e62da6ce..5f052d705e 100644 --- a/app/models/policies/levelling_up_premium_payments.rb +++ b/app/models/policies/levelling_up_premium_payments.rb @@ -12,6 +12,13 @@ module LevellingUpPremiumPayments AutomatedChecks::ClaimVerifiers::StudentLoanPlan ].freeze + # Used in + # - checking payments with multiple policies: ClaimsPreventingPaymentFinder + OTHER_CLAIMABLE_POLICIES = [ + EarlyCareerPayments, + StudentLoans + ].freeze + def notify_reply_to_id "03ece7eb-2a5b-461b-9c91-6630d0051aa6" end diff --git a/app/models/policies/student_loans.rb b/app/models/policies/student_loans.rb index e3f6294af1..1599ed40ca 100644 --- a/app/models/policies/student_loans.rb +++ b/app/models/policies/student_loans.rb @@ -25,6 +25,13 @@ module StudentLoans POLICY_END_YEAR = AcademicYear.new(2020).freeze ACADEMIC_YEARS_QUALIFIED_TEACHERS_CAN_CLAIM_FOR = 11 + # Used in + # - checking payments with multiple policies: ClaimsPreventingPaymentFinder + OTHER_CLAIMABLE_POLICIES = [ + EarlyCareerPayments, + LevellingUpPremiumPayments + ] + def eligibility_page_url "https://www.gov.uk/guidance/teachers-claim-back-your-student-loan-repayments" end From ccfe4c50bd0347fa7bc61dd35e230d120398a7de Mon Sep 17 00:00:00 2001 From: Kenneth Lee Date: Mon, 24 Jun 2024 19:34:47 +0100 Subject: [PATCH 19/66] MatchingAttributeFinder - config moved to Policy level --- app/models/base_policy.rb | 8 ++- app/models/claim/matching_attribute_finder.rb | 24 +------ app/models/policies/early_career_payments.rb | 3 + .../policies/levelling_up_premium_payments.rb | 3 + app/models/policies/student_loans.rb | 3 + spec/models/base_policy_spec.rb | 62 +++++++++++++++++++ 6 files changed, 80 insertions(+), 23 deletions(-) diff --git a/app/models/base_policy.rb b/app/models/base_policy.rb index f0a6810f36..2cfda2da62 100644 --- a/app/models/base_policy.rb +++ b/app/models/base_policy.rb @@ -26,7 +26,7 @@ def payroll_file_name end def policies_claimable - return [] unless self.const_defined?(:OTHER_CLAIMABLE_POLICIES) + return [] unless const_defined?(:OTHER_CLAIMABLE_POLICIES) [self] + self::OTHER_CLAIMABLE_POLICIES end @@ -34,4 +34,10 @@ def policies_claimable def policy_eligibilities_claimable policies_claimable.map { |p| p::Eligibility } end + + def eligibility_matching_attributes + return [] unless const_defined?(:ELIGIBILITY_MATCHING_ATTRIBUTES) + + self::ELIGIBILITY_MATCHING_ATTRIBUTES + end end diff --git a/app/models/claim/matching_attribute_finder.rb b/app/models/claim/matching_attribute_finder.rb index dbf4f650b9..710601bb92 100644 --- a/app/models/claim/matching_attribute_finder.rb +++ b/app/models/claim/matching_attribute_finder.rb @@ -1,18 +1,5 @@ class Claim class MatchingAttributeFinder - STUDENT_LOANS_AND_ADDITIONAL_PAYMENTS_GROUP = [ - Policies::StudentLoans, - Policies::EarlyCareerPayments, - Policies::LevellingUpPremiumPayments - ] - - # From the source_claim use this determine which group to use for comparison - CROSS_POLICY_MATCH_GROUPS = { - Policies::StudentLoans => STUDENT_LOANS_AND_ADDITIONAL_PAYMENTS_GROUP, - Policies::EarlyCareerPayments => STUDENT_LOANS_AND_ADDITIONAL_PAYMENTS_GROUP, - Policies::LevellingUpPremiumPayments => STUDENT_LOANS_AND_ADDITIONAL_PAYMENTS_GROUP - } - # Fields on the claim model to consider a match CLAIM_ATTRIBUTE_GROUPS_TO_MATCH = [ ["email_address"], @@ -20,13 +7,6 @@ class MatchingAttributeFinder ["bank_account_number", "bank_sort_code", "building_society_roll_number"] ].freeze - # Fields on the eligibility that are considered a match - ELIGIBILITY_ATTRIBUTE_GROUPS_TO_MATCH = { - Policies::StudentLoans => [["teacher_reference_number"]], - Policies::EarlyCareerPayments => [["teacher_reference_number"]], - Policies::LevellingUpPremiumPayments => [["teacher_reference_number"]] - } - def initialize(source_claim) @source_claim = source_claim end @@ -75,11 +55,11 @@ def matching_claims private def policies_to_find_matches - CROSS_POLICY_MATCH_GROUPS[@source_claim.policy] + @source_claim.policy.policies_claimable end def eligibility_attributes_groups_to_match - ELIGIBILITY_ATTRIBUTE_GROUPS_TO_MATCH[@source_claim.policy] + @source_claim.policy.eligibility_matching_attributes end def policies_to_find_matches_eligibility_types diff --git a/app/models/policies/early_career_payments.rb b/app/models/policies/early_career_payments.rb index 94280c8da2..731b4efa34 100644 --- a/app/models/policies/early_career_payments.rb +++ b/app/models/policies/early_career_payments.rb @@ -26,11 +26,14 @@ module EarlyCareerPayments # Used in # - checking payments with multiple policies: ClaimsPreventingPaymentFinder + # - matching claims with multiple policies: MatchingAttributeFinder OTHER_CLAIMABLE_POLICIES = [ LevellingUpPremiumPayments, StudentLoans ].freeze + ELIGIBILITY_MATCHING_ATTRIBUTES = [["teacher_reference_number"]].freeze + def eligibility_page_url "https://www.gov.uk/guidance/early-career-payments-guidance-for-teachers-and-schools" end diff --git a/app/models/policies/levelling_up_premium_payments.rb b/app/models/policies/levelling_up_premium_payments.rb index 5f052d705e..d30eb92d9f 100644 --- a/app/models/policies/levelling_up_premium_payments.rb +++ b/app/models/policies/levelling_up_premium_payments.rb @@ -14,11 +14,14 @@ module LevellingUpPremiumPayments # Used in # - checking payments with multiple policies: ClaimsPreventingPaymentFinder + # - matching claims with multiple policies: MatchingAttributeFinder OTHER_CLAIMABLE_POLICIES = [ EarlyCareerPayments, StudentLoans ].freeze + ELIGIBILITY_MATCHING_ATTRIBUTES = [["teacher_reference_number"]].freeze + def notify_reply_to_id "03ece7eb-2a5b-461b-9c91-6630d0051aa6" end diff --git a/app/models/policies/student_loans.rb b/app/models/policies/student_loans.rb index 1599ed40ca..b1e7e93609 100644 --- a/app/models/policies/student_loans.rb +++ b/app/models/policies/student_loans.rb @@ -27,11 +27,14 @@ module StudentLoans # Used in # - checking payments with multiple policies: ClaimsPreventingPaymentFinder + # - matching claims with multiple policies: MatchingAttributeFinder OTHER_CLAIMABLE_POLICIES = [ EarlyCareerPayments, LevellingUpPremiumPayments ] + ELIGIBILITY_MATCHING_ATTRIBUTES = [["teacher_reference_number"]].freeze + def eligibility_page_url "https://www.gov.uk/guidance/teachers-claim-back-your-student-loan-repayments" end diff --git a/spec/models/base_policy_spec.rb b/spec/models/base_policy_spec.rb index 6f0ca71125..c9eb30e4af 100644 --- a/spec/models/base_policy_spec.rb +++ b/spec/models/base_policy_spec.rb @@ -1,10 +1,38 @@ require "rails_helper" module Policies + module TestPolicyA + include BasePolicy + + extend self + + class Eligibility + end + end + + module TestPolicyB + include BasePolicy + + extend self + + class Eligibility + end + end + module TestPolicy include BasePolicy extend self + + OTHER_CLAIMABLE_POLICIES = [ + TestPolicyA, + TestPolicyB + ].freeze + + ELIGIBILITY_MATCHING_ATTRIBUTES = [["some_reference"]].freeze + + class Eligibility + end end end @@ -38,4 +66,38 @@ module TestPolicy expect(Policies::TestPolicy.locale_key).to eq("test_policy") end end + + describe "::policies_claimable" do + it do + expect(Policies::TestPolicy.policies_claimable).to contain_exactly( + Policies::TestPolicy, Policies::TestPolicyA, Policies::TestPolicyB + ) + end + + it do + expect(Policies::TestPolicyA.policies_claimable).to be_empty + end + end + + describe "::policy_eligibilities_claimable" do + it do + expect(Policies::TestPolicy.policy_eligibilities_claimable).to contain_exactly( + Policies::TestPolicy::Eligibility, Policies::TestPolicyA::Eligibility, Policies::TestPolicyB::Eligibility + ) + end + + it do + expect(Policies::TestPolicyA.policy_eligibilities_claimable).to be_empty + end + end + + describe "::eligibility_matching_attributes" do + it do + expect(Policies::TestPolicy.eligibility_matching_attributes).to contain_exactly(["some_reference"]) + end + + it do + expect(Policies::TestPolicyA.eligibility_matching_attributes).to be_empty + end + end end From 661d7a7a0cd4f93b205a7241ae504126a0886aff Mon Sep 17 00:00:00 2001 From: Kenneth Lee Date: Tue, 25 Jun 2024 09:49:59 +0100 Subject: [PATCH 20/66] Search - use Policy level config --- app/helpers/admin/claims_helper.rb | 2 +- app/models/base_policy.rb | 6 ++++++ app/models/claim/search.rb | 16 +++------------- app/models/policies/early_career_payments.rb | 2 ++ .../policies/levelling_up_premium_payments.rb | 2 ++ app/models/policies/student_loans.rb | 2 ++ spec/models/base_policy_spec.rb | 12 ++++++++++++ 7 files changed, 28 insertions(+), 14 deletions(-) diff --git a/app/helpers/admin/claims_helper.rb b/app/helpers/admin/claims_helper.rb index fc6cefde5c..be8c73a699 100644 --- a/app/helpers/admin/claims_helper.rb +++ b/app/helpers/admin/claims_helper.rb @@ -243,7 +243,7 @@ def matching_attributes_for_claim(claim) def matching_attributes_for_eligibility(eligibility) eligibility.attributes - .slice(*Claim::MatchingAttributeFinder::ELIGIBILITY_ATTRIBUTE_GROUPS_TO_MATCH[eligibility.policy].flatten) + .slice(*eligibility.policy.eligibility_matching_attributes.flatten) .reject { |_, v| v.blank? } .to_a end diff --git a/app/models/base_policy.rb b/app/models/base_policy.rb index 2cfda2da62..da9f4a0c42 100644 --- a/app/models/base_policy.rb +++ b/app/models/base_policy.rb @@ -40,4 +40,10 @@ def eligibility_matching_attributes self::ELIGIBILITY_MATCHING_ATTRIBUTES end + + def searchable_eligibility_attributes + return [] unless const_defined?(:SEARCHABLE_ELIGIBILITY_ATTRIBUTES) + + self::SEARCHABLE_ELIGIBILITY_ATTRIBUTES + end end diff --git a/app/models/claim/search.rb b/app/models/claim/search.rb index 2766df5b3c..7eb9df3e36 100644 --- a/app/models/claim/search.rb +++ b/app/models/claim/search.rb @@ -1,26 +1,16 @@ class Claim # Accepts a search term and returns all Claims that match against any of the - # attributes defined in the `SEARCHABLE_ATTRIBUTES` or `SEARCHABLE_ELIGIBILITY_ATTRIBUTES` constant. Both subject + # attributes defined in the `SEARCHABLE_ATTRIBUTES` or `policy::SEARCHABLE_ELIGIBILITY_ATTRIBUTES` constant. Both subject # and attribute are downcased, so the search is case-insensitive. class Search attr_accessor :search_term - POLICIES = [ - Policies::StudentLoans, - Policies::EarlyCareerPayments, - Policies::LevellingUpPremiumPayments - ] - SEARCHABLE_CLAIM_ATTRIBUTES = %w[ reference email_address surname ] - SEARCHABLE_ELIGIBILITY_ATTRIBUTES = %w[ - teacher_reference_number - ] - def initialize(search_term) @search_term = search_term end @@ -30,8 +20,8 @@ def claims relation.or(search_by(attribute)) } - eligibility_ids = SEARCHABLE_ELIGIBILITY_ATTRIBUTES.map { |attribute| - POLICIES.map { |policy| + eligibility_ids = Policies::POLICIES.map { |policy| + policy.searchable_eligibility_attributes.map { |attribute| policy::Eligibility.where("LOWER(#{attribute}) = LOWER(?)", search_term) } }.flatten.map(&:id) diff --git a/app/models/policies/early_career_payments.rb b/app/models/policies/early_career_payments.rb index 731b4efa34..946a59b1c0 100644 --- a/app/models/policies/early_career_payments.rb +++ b/app/models/policies/early_career_payments.rb @@ -34,6 +34,8 @@ module EarlyCareerPayments ELIGIBILITY_MATCHING_ATTRIBUTES = [["teacher_reference_number"]].freeze + SEARCHABLE_ELIGIBILITY_ATTRIBUTES = %w[teacher_reference_number].freeze + def eligibility_page_url "https://www.gov.uk/guidance/early-career-payments-guidance-for-teachers-and-schools" end diff --git a/app/models/policies/levelling_up_premium_payments.rb b/app/models/policies/levelling_up_premium_payments.rb index d30eb92d9f..57c9072399 100644 --- a/app/models/policies/levelling_up_premium_payments.rb +++ b/app/models/policies/levelling_up_premium_payments.rb @@ -22,6 +22,8 @@ module LevellingUpPremiumPayments ELIGIBILITY_MATCHING_ATTRIBUTES = [["teacher_reference_number"]].freeze + SEARCHABLE_ELIGIBILITY_ATTRIBUTES = %w[teacher_reference_number].freeze + def notify_reply_to_id "03ece7eb-2a5b-461b-9c91-6630d0051aa6" end diff --git a/app/models/policies/student_loans.rb b/app/models/policies/student_loans.rb index b1e7e93609..a39eda968a 100644 --- a/app/models/policies/student_loans.rb +++ b/app/models/policies/student_loans.rb @@ -35,6 +35,8 @@ module StudentLoans ELIGIBILITY_MATCHING_ATTRIBUTES = [["teacher_reference_number"]].freeze + SEARCHABLE_ELIGIBILITY_ATTRIBUTES = %w[teacher_reference_number].freeze + def eligibility_page_url "https://www.gov.uk/guidance/teachers-claim-back-your-student-loan-repayments" end diff --git a/spec/models/base_policy_spec.rb b/spec/models/base_policy_spec.rb index c9eb30e4af..abc200c266 100644 --- a/spec/models/base_policy_spec.rb +++ b/spec/models/base_policy_spec.rb @@ -31,6 +31,8 @@ module TestPolicy ELIGIBILITY_MATCHING_ATTRIBUTES = [["some_reference"]].freeze + SEARCHABLE_ELIGIBILITY_ATTRIBUTES = %w[some_searchable_reference].freeze + class Eligibility end end @@ -100,4 +102,14 @@ class Eligibility expect(Policies::TestPolicyA.eligibility_matching_attributes).to be_empty end end + + describe "::searchable_eligibility_attributes" do + it do + expect(Policies::TestPolicy.searchable_eligibility_attributes).to contain_exactly("some_searchable_reference") + end + + it do + expect(Policies::TestPolicyA.searchable_eligibility_attributes).to be_empty + end + end end From 8348375d99e7aa1985060d536d07bf0ae3b808b8 Mon Sep 17 00:00:00 2001 From: Kenneth Lee Date: Wed, 26 Jun 2024 10:07:39 +0100 Subject: [PATCH 21/66] Block TRN from DfE-analytics --- config/analytics.yml | 3 --- config/analytics_blocklist.yml | 9 +++++++-- 2 files changed, 7 insertions(+), 5 deletions(-) diff --git a/config/analytics.yml b/config/analytics.yml index 446c53c6f0..1f02b9d51d 100644 --- a/config/analytics.yml +++ b/config/analytics.yml @@ -151,7 +151,6 @@ shared: - had_leadership_position - mostly_performed_leadership_duties - claim_school_somewhere_else - - teacher_reference_number :early_career_payments_eligibilities: - id - nqt_in_academic_year_after_itt @@ -170,7 +169,6 @@ shared: - award_amount - induction_completed - school_somewhere_else - - teacher_reference_number :levelling_up_premium_payments_eligibilities: - id - created_at @@ -190,7 +188,6 @@ shared: - eligible_degree_subject - induction_completed - school_somewhere_else - - teacher_reference_number :international_relocation_payments_eligibilities: - id - created_at diff --git a/config/analytics_blocklist.yml b/config/analytics_blocklist.yml index f50bb151b0..e353302397 100644 --- a/config/analytics_blocklist.yml +++ b/config/analytics_blocklist.yml @@ -19,7 +19,7 @@ - building_society_roll_number - banking_name - mobile_number - - teacher_reference_number + - column_to_remove_teacher_reference_number - email_address - payroll_gender - one_time_password @@ -98,4 +98,9 @@ - gender_digit :international_relocation_payments_eligibilities: - passport_number - + :levelling_up_premium_payments_eligibilities: + - teacher_reference_number + :early_career_payments_eligibilities: + - teacher_reference_number + :student_loans_eligibilities: + - teacher_reference_number From 4dfb78033eb6801841d1501c2d107a66854284a4 Mon Sep 17 00:00:00 2001 From: Steven Lorek Date: Wed, 26 Jun 2024 17:06:27 +0100 Subject: [PATCH 22/66] Fix production deploys being skipped (#2923) --- azure-pipelines.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/azure-pipelines.yml b/azure-pipelines.yml index 0fa70dcf98..295ca84de2 100644 --- a/azure-pipelines.yml +++ b/azure-pipelines.yml @@ -25,7 +25,7 @@ stages: - stage: ProductionRelease lockBehavior: sequential - condition: and(succeeded('TestRelease'), eq(variables['Build.SourceBranch'], 'refs/heads/master')) + condition: eq(variables['Build.SourceBranch'], 'refs/heads/master') jobs: - deployment: ProductionRelease displayName: Deploy to production environment From 00c0d9af05170df73742e0a9882f906945c5ba5e Mon Sep 17 00:00:00 2001 From: Giuseppe Lobraico Date: Wed, 26 Jun 2024 17:20:04 +0100 Subject: [PATCH 23/66] CAPT-1419 ECP exit screen showing incorrect text for AY24-25 (when induction not completed) (#2766) * Move last policy year value to `Policies::EarlyCareerPayments` For consistency with the Student Loans policy * Move last policy year value to `Policies::LevellingUpPremiumPayments` For consistency with the Student Loans policy Add the first policy year value as well. * Remove redundant methods from `Policies::EarlyCareerPayments` These were created a while ago for consistency with Student Loans, but the meaning here is completely different and misleading. The QTS Award year is not linked to the policy start/end year. * Use `#any_future_policy_years?` to evaluate against the the policy specific end year * Fix eligibility criteria url for ECP * Make sure an ECP claim is ineligible when induction not completed and it's the end year for ECP For years previous to the final one, if a user selected an ECP-only school (meaning the LUPP claim is ineligible), and answered "No" to the induction question, they'd be able to see the eligible-later slug and set up a reminder. * Fix copy * Use session answers instead of claim object * Fix bug in ineligible page * Remove shim class workaround --------- Co-authored-by: Steve Lorek --- app/models/concerns/eligibility_checkable.rb | 10 ++++++++- .../early_career_payments/eligible.rb | 4 ++-- .../slug_sequence.rb | 5 +++-- app/models/policies/early_career_payments.rb | 9 +------- .../early_career_payments/eligibility.rb | 3 +-- .../policies/levelling_up_premium_payments.rb | 5 ++++- .../eligibility.rb | 3 +-- ..._ecp_only_induction_not_completed.html.erb | 17 +++++++++++++++ ...ility_trainee_in_last_policy_year.html.erb | 2 +- lib/ineligibility_reason_checker.rb | 13 ++++++++++-- .../session_answers.rb | 6 ++++++ ...gible_early_career_payments_claims_spec.rb | 21 +++++++++++++++++++ spec/models/early_career_payments_spec.rb | 6 ------ .../levelling_up_premium_payments_spec.rb | 2 +- .../policy_eligibility_checker_spec.rb | 14 ++++++++----- 15 files changed, 87 insertions(+), 33 deletions(-) create mode 100644 app/views/additional_payments/claims/_ineligibility_ecp_only_induction_not_completed.html.erb diff --git a/app/models/concerns/eligibility_checkable.rb b/app/models/concerns/eligibility_checkable.rb index 4d77e87140..77cd0f2dda 100644 --- a/app/models/concerns/eligibility_checkable.rb +++ b/app/models/concerns/eligibility_checkable.rb @@ -121,10 +121,18 @@ def sufficient_teaching? end def common_eligible_later_attributes? - any_future_policy_years? && indicated_eligible_school? + any_future_combined_policy_years? && indicated_eligible_school? + end + + def policy_end_year + policy::POLICY_END_YEAR end def any_future_policy_years? + claim_year < policy_end_year + end + + def any_future_combined_policy_years? claim_year < FINAL_COMBINED_ECP_AND_LUP_POLICY_YEAR end end diff --git a/app/models/concerns/policies/early_career_payments/eligible.rb b/app/models/concerns/policies/early_career_payments/eligible.rb index 6e76ff7152..6899541abb 100644 --- a/app/models/concerns/policies/early_career_payments/eligible.rb +++ b/app/models/concerns/policies/early_career_payments/eligible.rb @@ -42,7 +42,7 @@ def itt_subject_eligible_now? end def specific_ineligible_attributes? - trainee_teacher? || (induction_not_completed? && !ecp_only_school?) || itt_subject_ineligible_now_and_in_the_future? + trainee_teacher? || (induction_not_completed? && !any_future_policy_years?) || itt_subject_ineligible_now_and_in_the_future? end def itt_subject_ineligible_now_and_in_the_future? @@ -55,7 +55,7 @@ def itt_subject_ineligible_now_and_in_the_future? end def specific_eligible_later_attributes? - newly_qualified_teacher? && ((induction_not_completed? && ecp_only_school?) || (!itt_subject_eligible_now? && itt_subject_eligible_later?)) + newly_qualified_teacher? && ((induction_not_completed? && any_future_policy_years?) || (!itt_subject_eligible_now? && itt_subject_eligible_later?)) end def itt_subject_eligible_later? diff --git a/app/models/journeys/additional_payments_for_teaching/slug_sequence.rb b/app/models/journeys/additional_payments_for_teaching/slug_sequence.rb index 29cea1c0b8..2581ae2f17 100644 --- a/app/models/journeys/additional_payments_for_teaching/slug_sequence.rb +++ b/app/models/journeys/additional_payments_for_teaching/slug_sequence.rb @@ -184,12 +184,13 @@ def personal_details_form end def replace_ecp_only_induction_not_completed_slugs(sequence) + dead_end_slug = (ecp_eligibility_checker.status == :eligible_later) ? "eligible-later" : "ineligible" + slugs = %w[ current-school nqt-in-academic-year-after-itt induction-completed - eligible-later - ] + ] << dead_end_slug sequence.replace(slugs) end diff --git a/app/models/policies/early_career_payments.rb b/app/models/policies/early_career_payments.rb index 946a59b1c0..8d6bffbe94 100644 --- a/app/models/policies/early_career_payments.rb +++ b/app/models/policies/early_career_payments.rb @@ -23,6 +23,7 @@ module EarlyCareerPayments ].freeze POLICY_START_YEAR = AcademicYear.new(2021).freeze + POLICY_END_YEAR = AcademicYear.new(2024).freeze # Used in # - checking payments with multiple policies: ClaimsPreventingPaymentFinder @@ -48,14 +49,6 @@ def notify_reply_to_id "3f85a1f7-9400-4b48-9a31-eaa643d6b977" end - def first_eligible_qts_award_year(claim_year = nil) - POLICY_START_YEAR - end - - def last_ineligible_qts_award_year - first_eligible_qts_award_year - 1 - end - def student_loan_balance_url "https://www.gov.uk/sign-in-to-manage-your-student-loan-balance" end diff --git a/app/models/policies/early_career_payments/eligibility.rb b/app/models/policies/early_career_payments/eligibility.rb index b01583141e..d55458fdd8 100644 --- a/app/models/policies/early_career_payments/eligibility.rb +++ b/app/models/policies/early_career_payments/eligibility.rb @@ -16,7 +16,6 @@ def policy self.table_name = "early_career_payments_eligibilities" FIRST_ITT_AY = "2016/2017" - LAST_POLICY_YEAR = "2024/2025" # Generates an object similar to # { @@ -31,7 +30,7 @@ def policy # and the enums would be stale until after a server restart. # Make all valid ITT values based on the last known policy year. ITT_ACADEMIC_YEARS = - (AcademicYear.new(FIRST_ITT_AY)...AcademicYear.new(LAST_POLICY_YEAR)).each_with_object({}) do |year, hsh| + (AcademicYear.new(FIRST_ITT_AY)...POLICY_END_YEAR).each_with_object({}) do |year, hsh| hsh[year] = AcademicYear::Type.new.serialize(year) end.merge({AcademicYear.new => AcademicYear::Type.new.serialize(AcademicYear.new)}) diff --git a/app/models/policies/levelling_up_premium_payments.rb b/app/models/policies/levelling_up_premium_payments.rb index 57c9072399..052fa437bb 100644 --- a/app/models/policies/levelling_up_premium_payments.rb +++ b/app/models/policies/levelling_up_premium_payments.rb @@ -24,6 +24,9 @@ module LevellingUpPremiumPayments SEARCHABLE_ELIGIBILITY_ATTRIBUTES = %w[teacher_reference_number].freeze + POLICY_START_YEAR = AcademicYear.new(2022).freeze + POLICY_END_YEAR = AcademicYear.new(2024).freeze + def notify_reply_to_id "03ece7eb-2a5b-461b-9c91-6630d0051aa6" end @@ -33,7 +36,7 @@ def eligibility_page_url end def eligibility_criteria_url - eligibility_page_url + "#eligibility-criteria-for-teachers" + eligibility_page_url + "#eligibility-criteria" end def payment_and_deductions_info_url diff --git a/app/models/policies/levelling_up_premium_payments/eligibility.rb b/app/models/policies/levelling_up_premium_payments/eligibility.rb index 042b95ba67..4010fef8d1 100644 --- a/app/models/policies/levelling_up_premium_payments/eligibility.rb +++ b/app/models/policies/levelling_up_premium_payments/eligibility.rb @@ -24,7 +24,6 @@ def policy AMENDABLE_ATTRIBUTES = [:teacher_reference_number, :award_amount].freeze FIRST_ITT_AY = "2017/2018" - LAST_POLICY_YEAR = "2024/2025" # Generates an object similar to # { @@ -39,7 +38,7 @@ def policy # and the enums would be stale until after a server restart. # Make all valid ITT values based on the last known policy year. ITT_ACADEMIC_YEARS = - (AcademicYear.new(FIRST_ITT_AY)...AcademicYear.new(LAST_POLICY_YEAR)).each_with_object({}) do |year, hsh| + (AcademicYear.new(FIRST_ITT_AY)...POLICY_END_YEAR).each_with_object({}) do |year, hsh| hsh[year] = AcademicYear::Type.new.serialize(year) end.merge({AcademicYear.new => AcademicYear::Type.new.serialize(AcademicYear.new)}) diff --git a/app/views/additional_payments/claims/_ineligibility_ecp_only_induction_not_completed.html.erb b/app/views/additional_payments/claims/_ineligibility_ecp_only_induction_not_completed.html.erb new file mode 100644 index 0000000000..4496c285ff --- /dev/null +++ b/app/views/additional_payments/claims/_ineligibility_ecp_only_induction_not_completed.html.erb @@ -0,0 +1,17 @@ +

+ You are not eligible for the + <%= link_to("early-career payment (opens in new tab)", Policies::EarlyCareerPayments.eligibility_criteria_url, class: "govuk-link", target: "_blank") %> + because you have not completed your induction. +

+

+ You are not eligible for the + <%= link_to("levelling up premium payment (opens in new tab)", Policies::LevellingUpPremiumPayments.eligibility_criteria_url, class: "govuk-link", target: "_blank") %> + because the school you teach in is not eligible. Levelling up premium payments are offered in schools identified as having a higher need for teachers. +

+ +

+ For more information, check the eligibility criteria for + <%= link_to("early-career payments", Policies::EarlyCareerPayments.eligibility_criteria_url, class: "govuk-link") %> + and + <%= link_to("levelling up premium payments", Policies::LevellingUpPremiumPayments.eligibility_criteria_url, class: "govuk-link") %>. +

diff --git a/app/views/additional_payments/claims/_ineligibility_trainee_in_last_policy_year.html.erb b/app/views/additional_payments/claims/_ineligibility_trainee_in_last_policy_year.html.erb index 9a9c4aac8d..ae8a10e8e6 100644 --- a/app/views/additional_payments/claims/_ineligibility_trainee_in_last_policy_year.html.erb +++ b/app/views/additional_payments/claims/_ineligibility_trainee_in_last_policy_year.html.erb @@ -6,7 +6,7 @@ You will not be eligible for the <%= link_to("early-career payment", Policies::EarlyCareerPayments.eligibility_criteria_url, class: "govuk-link") %> or the - <%= link_to("levelling up premium payment", LevellingUpPremiumPayments.eligibility_criteria_url, class: "govuk-link") %> + <%= link_to("levelling up premium payment", Policies::LevellingUpPremiumPayments.eligibility_criteria_url, class: "govuk-link") %> once you start work as a qualified teacher.

diff --git a/lib/ineligibility_reason_checker.rb b/lib/ineligibility_reason_checker.rb index c9085659ea..8362bbf821 100644 --- a/lib/ineligibility_reason_checker.rb +++ b/lib/ineligibility_reason_checker.rb @@ -16,6 +16,8 @@ def reason :generic elsif trainee_teacher_last_policy_year? :trainee_in_last_policy_year + elsif ecp_only_induction_not_completed? + :ecp_only_induction_not_completed elsif ecp_only_trainee_teacher? :ecp_only_trainee_teacher elsif trainee_teaching_lacking_both_valid_itt_subject_and_degree? @@ -83,6 +85,13 @@ def generic? ].any? end + def ecp_only_induction_not_completed? + [ + school_eligible_for_ecp_but_not_lup?(@answers.current_school), + @answers.induction_not_completed? + ].all? + end + def ecp_only_trainee_teacher? [ !Policies::LevellingUpPremiumPayments::SchoolEligibility.new(@answers.current_school).eligible?, @@ -181,8 +190,8 @@ def no_ecp_subjects_that_itt_year? def trainee_teacher_last_policy_year? [ @answers.nqt_in_academic_year_after_itt == false, - @answers.academic_year >= AcademicYear.new(Policies::LevellingUpPremiumPayments::Eligibility::LAST_POLICY_YEAR), - @answers.academic_year >= AcademicYear.new(Policies::EarlyCareerPayments::Eligibility::LAST_POLICY_YEAR) + @answers.academic_year >= AcademicYear.new(Policies::LevellingUpPremiumPayments::POLICY_END_YEAR), + @answers.academic_year >= AcademicYear.new(Policies::EarlyCareerPayments::POLICY_END_YEAR) ].all? end end diff --git a/spec/factories/journeys/additional_payments_for_teaching/session_answers.rb b/spec/factories/journeys/additional_payments_for_teaching/session_answers.rb index 6847b81ba5..1c051a91e8 100644 --- a/spec/factories/journeys/additional_payments_for_teaching/session_answers.rb +++ b/spec/factories/journeys/additional_payments_for_teaching/session_answers.rb @@ -179,6 +179,12 @@ end end + trait :eligible_school_ecp_only do + current_school_id do + create(:school, :early_career_payments_eligible, :levelling_up_premium_payments_ineligible).id + end + end + trait :short_term_supply_teacher do employed_as_supply_teacher { true } has_entire_term_contract { false } diff --git a/spec/features/ineligible_early_career_payments_claims_spec.rb b/spec/features/ineligible_early_career_payments_claims_spec.rb index 0974155eee..67b558c0de 100644 --- a/spec/features/ineligible_early_career_payments_claims_spec.rb +++ b/spec/features/ineligible_early_career_payments_claims_spec.rb @@ -20,6 +20,27 @@ expect(page).to have_text("The school you have selected is not eligible") end + scenario "induction not completed and it's the last policy year" do + Journeys.for_policy(Policies::EarlyCareerPayments).configuration.update!(current_academic_year: Policies::EarlyCareerPayments::POLICY_END_YEAR) + + start_early_career_payments_claim + + skip_tid + + choose_school eligible_school + + # - Are you currently teaching as a qualified teacher? + choose "Yes" + click_on "Continue" + + # - Have you completed your induction as an early-career teacher? + choose "No" + click_on "Continue" + + expect(page).to have_text(I18n.t("additional_payments.ineligible.heading")) + expect(page).to have_css("div#ecp_only_induction_not_completed") + end + scenario "when poor performance - subject to formal performance action" do start_early_career_payments_claim diff --git a/spec/models/early_career_payments_spec.rb b/spec/models/early_career_payments_spec.rb index 1b30620d50..1c71e9cffd 100644 --- a/spec/models/early_career_payments_spec.rb +++ b/spec/models/early_career_payments_spec.rb @@ -26,12 +26,6 @@ ) } - describe ".first_eligible_qts_award_year" do - it "can return the AcademicYear based on a passed-in academic year" do - expect(described_class.first_eligible_qts_award_year(AcademicYear.new(2024))).to eq AcademicYear.new(2021) - end - end - describe ".payroll_file_name" do subject(:payroll_file_name) { described_class.payroll_file_name } it { is_expected.to eq("EarlyCareerPayments") } diff --git a/spec/models/levelling_up_premium_payments_spec.rb b/spec/models/levelling_up_premium_payments_spec.rb index 4c94cd8957..6e9171222b 100644 --- a/spec/models/levelling_up_premium_payments_spec.rb +++ b/spec/models/levelling_up_premium_payments_spec.rb @@ -19,7 +19,7 @@ locale_key: "levelling_up_premium_payments", notify_reply_to_id: "03ece7eb-2a5b-461b-9c91-6630d0051aa6", eligibility_page_url: "https://www.gov.uk/guidance/levelling-up-premium-payments-for-teachers", - eligibility_criteria_url: "https://www.gov.uk/guidance/levelling-up-premium-payments-for-teachers#eligibility-criteria-for-teachers", + eligibility_criteria_url: "https://www.gov.uk/guidance/levelling-up-premium-payments-for-teachers#eligibility-criteria", payment_and_deductions_info_url: "https://www.gov.uk/guidance/levelling-up-premium-payments-for-teachers#payments-and-deductions" ) } diff --git a/spec/models/policies/early_career_payments/policy_eligibility_checker_spec.rb b/spec/models/policies/early_career_payments/policy_eligibility_checker_spec.rb index e63522ca38..2c93460015 100644 --- a/spec/models/policies/early_career_payments/policy_eligibility_checker_spec.rb +++ b/spec/models/policies/early_career_payments/policy_eligibility_checker_spec.rb @@ -72,7 +72,9 @@ end describe "#status" do - before { create(:journey_configuration, :additional_payments) } + let(:claim_year) { AcademicYear.new(2022) } + + before { create(:journey_configuration, :additional_payments, current_academic_year: claim_year) } subject { policy_eligibility_checker.status } @@ -111,14 +113,16 @@ end context "induction not completed" do - context "with an ECP-only eligible school" do - let(:answers) { build(:additional_payments_answers, :ecp_eligible, induction_completed: false) } + let(:answers) { build(:additional_payments_answers, :ecp_eligible, :eligible_school_ecp_only, induction_completed: false) } + + context "when the claim year is not the same as the end policy year" do + let(:claim_year) { Policies::EarlyCareerPayments::POLICY_END_YEAR - 1 } it { is_expected.to eq(:eligible_later) } end - context "with an ECP and LUP eligible school" do - let(:answers) { build(:additional_payments_answers, :ecp_eligible, :eligible_school_ecp_and_lup, induction_completed: false) } + context "when the claim year is the same as the end policy year" do + let(:claim_year) { Policies::EarlyCareerPayments::POLICY_END_YEAR } it { is_expected.to eq(:ineligible) } end From 727213632d38ce1c9f363a787480acb225c5e10a Mon Sep 17 00:00:00 2001 From: Kenneth Lee Date: Wed, 26 Jun 2024 18:39:30 +0100 Subject: [PATCH 24/66] Bugfix empty pii yaml file needs to be an empty hash (#2929) --- config/analytics_pii.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/config/analytics_pii.yml b/config/analytics_pii.yml index 2f56046b2b..3a42532a18 100644 --- a/config/analytics_pii.yml +++ b/config/analytics_pii.yml @@ -1,2 +1,2 @@ --- -shared: +shared: {} From 5895f1e188641f088f0a974851b0afc8d2d78505 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Wed, 26 Jun 2024 18:45:40 +0100 Subject: [PATCH 25/66] Bump pagy from 8.4.5 to 8.5.0 (#2917) Bumps [pagy](https://github.com/ddnexus/pagy) from 8.4.5 to 8.5.0. - [Release notes](https://github.com/ddnexus/pagy/releases) - [Changelog](https://github.com/ddnexus/pagy/blob/master/CHANGELOG.md) - [Commits](https://github.com/ddnexus/pagy/compare/8.4.5...8.5.0) --- updated-dependencies: - dependency-name: pagy dependency-type: direct:production update-type: version-update:semver-minor ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- Gemfile.lock | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Gemfile.lock b/Gemfile.lock index 63451c77b3..c4166d55c0 100644 --- a/Gemfile.lock +++ b/Gemfile.lock @@ -320,7 +320,7 @@ GEM validate_url webfinger (~> 1.2) os (1.1.4) - pagy (8.4.5) + pagy (8.5.0) parallel (1.25.1) parallel_tests (4.7.1) parallel From a100f0b1e2cd6204d5aa04512c5160622225eca8 Mon Sep 17 00:00:00 2001 From: Phil Lee Date: Thu, 27 Jun 2024 11:28:30 +0100 Subject: [PATCH 26/66] add subject areas to FE journey - also added form#t to aid in translations for forms - form strong paramsters now handles checkboxes ie collections --- app/forms/form.rb | 23 ++++++-- .../subjects_taught_form.rb | 41 +++++++++++++ .../journeys/further_education_payments.rb | 3 +- .../session_answers.rb | 1 + .../slug_sequence.rb | 2 +- .../claims/subject_areas.html.erb | 7 --- .../claims/subjects_taught.html.erb | 28 +++++++++ config/locales/en.yml | 5 ++ .../happy_js_path_spec.rb | 3 +- .../happy_path_spec.rb | 3 +- .../subjects_taught_form_spec.rb | 59 +++++++++++++++++++ 11 files changed, 159 insertions(+), 16 deletions(-) create mode 100644 app/forms/journeys/further_education_payments/subjects_taught_form.rb delete mode 100644 app/views/further_education_payments/claims/subject_areas.html.erb create mode 100644 app/views/further_education_payments/claims/subjects_taught.html.erb create mode 100644 spec/forms/journeys/further_education_payments/subjects_taught_form_spec.rb diff --git a/app/forms/form.rb b/app/forms/form.rb index b36551e956..7c58c945b7 100644 --- a/app/forms/form.rb +++ b/app/forms/form.rb @@ -38,6 +38,10 @@ def i18n_errors_path(msg, args = {}) I18n.t("#{i18n_namespace}.#{base_key}", default: base_key, **args) end + def t(key, args = {}) + I18n.t(key, scope: "#{i18n_namespace}.forms.#{i18n_form_namespace}", **args) + end + def permitted_params @permitted_params ||= params.fetch(model_name.param_key, {}).permit(*permitted_attributes) end @@ -49,7 +53,16 @@ def persisted? private def permitted_attributes - attribute_names + attributes.keys.map do |key| + field = @attributes[key] + + case field.value_before_type_cast + when [] + {key => []} + else + key + end + end end def i18n_form_namespace @@ -57,11 +70,11 @@ def i18n_form_namespace end def attributes_with_current_value - attributes.each_with_object({}) do |(attribute, _), attributes| - attributes[attribute] = permitted_params[attribute] - next unless attributes[attribute].nil? + attributes.each_with_object({}) do |(attribute, _), hash| + hash[attribute] = permitted_params[attribute] + next unless hash[attribute].nil? - attributes[attribute] = load_current_value(attribute) + hash[attribute] = load_current_value(attribute) end end diff --git a/app/forms/journeys/further_education_payments/subjects_taught_form.rb b/app/forms/journeys/further_education_payments/subjects_taught_form.rb new file mode 100644 index 0000000000..c012309232 --- /dev/null +++ b/app/forms/journeys/further_education_payments/subjects_taught_form.rb @@ -0,0 +1,41 @@ +module Journeys + module FurtherEducationPayments + class SubjectsTaughtForm < Form + include ActiveModel::Validations::Callbacks + + attribute :subjects_taught, default: [] + + before_validation :clean_subjects_taught + + validates :subjects_taught, + presence: {message: i18n_error_message(:inclusion)}, + inclusion: {in: ->(form) { form.radio_options.map(&:id) }, message: i18n_error_message(:inclusion)} + + def radio_options + [ + OpenStruct.new(id: "building-and-construction", name: "Building and construction"), + OpenStruct.new(id: "chemistry", name: "Chemistry"), + OpenStruct.new(id: "computing", name: "Computing, including digital and ICT"), + OpenStruct.new(id: "early-years", name: "Early years"), + OpenStruct.new(id: "engineering-and-manufacturing", name: "Engineering and manufacturing, including transport engineering and electronics"), + OpenStruct.new(id: "mathematics", name: "Mathematics"), + OpenStruct.new(id: "physics", name: "Physics"), + OpenStruct.new(id: "none", name: "I do not teach any of these subjects") + ] + end + + def save + return false unless valid? + + journey_session.answers.assign_attributes(subjects_taught:) + journey_session.save! + end + + private + + def clean_subjects_taught + subjects_taught.reject!(&:blank?) + end + end + end +end diff --git a/app/models/journeys/further_education_payments.rb b/app/models/journeys/further_education_payments.rb index 25b492b841..831bde3558 100644 --- a/app/models/journeys/further_education_payments.rb +++ b/app/models/journeys/further_education_payments.rb @@ -11,7 +11,8 @@ module FurtherEducationPayments "claims" => { "teaching-responsibilities" => TeachingResponsibilitiesForm, "further-education-provision-search" => FurtherEducationProvisionSearchForm, - "select-provision" => SelectProvisionForm + "select-provision" => SelectProvisionForm, + "subjects-taught" => SubjectsTaughtForm } } end diff --git a/app/models/journeys/further_education_payments/session_answers.rb b/app/models/journeys/further_education_payments/session_answers.rb index 014ee11a5b..07cedd8d3d 100644 --- a/app/models/journeys/further_education_payments/session_answers.rb +++ b/app/models/journeys/further_education_payments/session_answers.rb @@ -4,6 +4,7 @@ class SessionAnswers < Journeys::SessionAnswers attribute :teaching_responsibilities, :boolean attribute :provision_search, :string attribute :school_id, :string # GUID + attribute :subjects_taught, default: [] end end end diff --git a/app/models/journeys/further_education_payments/slug_sequence.rb b/app/models/journeys/further_education_payments/slug_sequence.rb index 9ae0f182ff..d9f41f5322 100644 --- a/app/models/journeys/further_education_payments/slug_sequence.rb +++ b/app/models/journeys/further_education_payments/slug_sequence.rb @@ -8,7 +8,7 @@ class SlugSequence contract-type teaching-hours-per-week academic-year-in-further-education - subject-areas + subjects-taught building-and-construction-courses teaching-courses half-teaching-hours diff --git a/app/views/further_education_payments/claims/subject_areas.html.erb b/app/views/further_education_payments/claims/subject_areas.html.erb deleted file mode 100644 index 46accd8c47..0000000000 --- a/app/views/further_education_payments/claims/subject_areas.html.erb +++ /dev/null @@ -1,7 +0,0 @@ -

- FE subject areas goes here -

- -<%= form_with model: @form, url: claim_path(current_journey_routing_name), method: :patch, builder: GOVUKDesignSystemFormBuilder::FormBuilder, html: { novalidate: false } do |f| %> - <%= f.govuk_submit %> -<% end %> diff --git a/app/views/further_education_payments/claims/subjects_taught.html.erb b/app/views/further_education_payments/claims/subjects_taught.html.erb new file mode 100644 index 0000000000..44b099d9d9 --- /dev/null +++ b/app/views/further_education_payments/claims/subjects_taught.html.erb @@ -0,0 +1,28 @@ +
+
+ <%= form_with model: @form, url: claim_path(current_journey_routing_name), method: :patch, builder: GOVUKDesignSystemFormBuilder::FormBuilder, html: { novalidate: false } do |f| %> + <%= f.govuk_error_summary %> + + <%= f.govuk_check_boxes_fieldset :subjects_taught, + legend: { + text: @form.t(:question), + tag: "h1", + size: "l" + }, + hint: { + text: @form.t(:hint) + } do %> + <% @form.radio_options[0..-2].each do |option| %> + <%= f.govuk_check_box :subjects_taught, option.id, label: { text: option.name }, link_errors: @form.radio_options.first == option %> + <% end %> + + <%= f.govuk_check_box_divider %> + + <% option = @form.radio_options.last %> + <%= f.govuk_check_box :subjects_taught, option.id, label: { text: option.name }, exclusive: true %> + <% end %> + + <%= f.govuk_submit %> + <% end %> +
+
diff --git a/config/locales/en.yml b/config/locales/en.yml index fe475c9927..91b9a890d1 100644 --- a/config/locales/en.yml +++ b/config/locales/en.yml @@ -777,6 +777,11 @@ en: select_provision: errors: blank: Select the college you teach at + subjects_taught: + question: Which subject areas do you teach? + hint: Select all that apply + errors: + inclusion: Select the subject areas you teach in or select you do not teach any of the listed subject areas activerecord: errors: models: diff --git a/spec/features/further_education_payments/happy_js_path_spec.rb b/spec/features/further_education_payments/happy_js_path_spec.rb index ff2c7e8c79..f3eb04fc25 100644 --- a/spec/features/further_education_payments/happy_js_path_spec.rb +++ b/spec/features/further_education_payments/happy_js_path_spec.rb @@ -35,7 +35,8 @@ expect(page).to have_content("FE academic year in further education goes here") click_button "Continue" - expect(page).to have_content("FE subject areas goes here") + expect(page).to have_content("Which subject areas do you teach?") + check("Building and construction") click_button "Continue" expect(page).to have_content("FE building and construction courses goes here") diff --git a/spec/features/further_education_payments/happy_path_spec.rb b/spec/features/further_education_payments/happy_path_spec.rb index 3468683ed2..03bd448a56 100644 --- a/spec/features/further_education_payments/happy_path_spec.rb +++ b/spec/features/further_education_payments/happy_path_spec.rb @@ -32,7 +32,8 @@ expect(page).to have_content("FE academic year in further education goes here") click_button "Continue" - expect(page).to have_content("FE subject areas goes here") + expect(page).to have_content("Which subject areas do you teach?") + check("Building and construction") click_button "Continue" expect(page).to have_content("FE building and construction courses goes here") diff --git a/spec/forms/journeys/further_education_payments/subjects_taught_form_spec.rb b/spec/forms/journeys/further_education_payments/subjects_taught_form_spec.rb new file mode 100644 index 0000000000..22f5c75266 --- /dev/null +++ b/spec/forms/journeys/further_education_payments/subjects_taught_form_spec.rb @@ -0,0 +1,59 @@ +require "rails_helper" + +RSpec.describe Journeys::FurtherEducationPayments::SubjectsTaughtForm, type: :model do + let(:journey) { Journeys::FurtherEducationPayments } + let(:journey_session) { create(:further_education_payments_session) } + let(:subjects_taught) { [] } + + let(:params) do + ActionController::Parameters.new( + claim: { + subjects_taught: + } + ) + end + + subject do + described_class.new( + journey_session:, + journey:, + params: + ) + end + + describe "validations" do + context "when no option selected" do + let(:subjects_taught) { [] } + + it do + is_expected.not_to( + allow_value([]) + .for(:subjects_taught) + .with_message("Select the subject areas you teach in or select you do not teach any of the listed subject areas") + ) + end + end + + context "when non-existent injection option selected" do + let(:subjects_taught) { ["foo"] } + + it do + is_expected.not_to( + allow_value(["foo"]) + .for(:subjects_taught) + .with_message("Select the subject areas you teach in or select you do not teach any of the listed subject areas") + ) + end + end + end + + describe "#save" do + let(:subjects_taught) { ["chemistry", "mathematics"] } + + it "updates the journey session" do + expect { expect(subject.save).to be(true) }.to( + change { journey_session.reload.answers.subjects_taught }.to(["chemistry", "mathematics"]) + ) + end + end +end From 9e03e496acc5a459a7bdbe08df8987e8e81e312f Mon Sep 17 00:00:00 2001 From: Phil Lee Date: Thu, 27 Jun 2024 13:35:25 +0100 Subject: [PATCH 27/66] refactor: improve method name --- .../further_education_payments/subjects_taught_form.rb | 4 ++-- .../claims/subjects_taught.html.erb | 6 +++--- 2 files changed, 5 insertions(+), 5 deletions(-) diff --git a/app/forms/journeys/further_education_payments/subjects_taught_form.rb b/app/forms/journeys/further_education_payments/subjects_taught_form.rb index c012309232..6831cab998 100644 --- a/app/forms/journeys/further_education_payments/subjects_taught_form.rb +++ b/app/forms/journeys/further_education_payments/subjects_taught_form.rb @@ -9,9 +9,9 @@ class SubjectsTaughtForm < Form validates :subjects_taught, presence: {message: i18n_error_message(:inclusion)}, - inclusion: {in: ->(form) { form.radio_options.map(&:id) }, message: i18n_error_message(:inclusion)} + inclusion: {in: ->(form) { form.checkbox_options.map(&:id) }, message: i18n_error_message(:inclusion)} - def radio_options + def checkbox_options [ OpenStruct.new(id: "building-and-construction", name: "Building and construction"), OpenStruct.new(id: "chemistry", name: "Chemistry"), diff --git a/app/views/further_education_payments/claims/subjects_taught.html.erb b/app/views/further_education_payments/claims/subjects_taught.html.erb index 44b099d9d9..3a85dcbeae 100644 --- a/app/views/further_education_payments/claims/subjects_taught.html.erb +++ b/app/views/further_education_payments/claims/subjects_taught.html.erb @@ -12,13 +12,13 @@ hint: { text: @form.t(:hint) } do %> - <% @form.radio_options[0..-2].each do |option| %> - <%= f.govuk_check_box :subjects_taught, option.id, label: { text: option.name }, link_errors: @form.radio_options.first == option %> + <% @form.checkbox_options[0..-2].each do |option| %> + <%= f.govuk_check_box :subjects_taught, option.id, label: { text: option.name }, link_errors: @form.checkbox_options.first == option %> <% end %> <%= f.govuk_check_box_divider %> - <% option = @form.radio_options.last %> + <% option = @form.checkbox_options.last %> <%= f.govuk_check_box :subjects_taught, option.id, label: { text: option.name }, exclusive: true %> <% end %> From c63385cc6b4b0690287c87b2727560249c0ed6e7 Mon Sep 17 00:00:00 2001 From: AbigailMcP Date: Thu, 27 Jun 2024 15:16:32 +0100 Subject: [PATCH 28/66] Update old documentation (#2912) Co-authored-by: Steven Lorek --- docs/connecting-to-azure.md | 36 +++++-- docs/developer-onboarding.md | 9 +- docs/docker-hub-credentials.md | 6 -- docs/first-line-support-developer-runbook.md | 7 -- docs/infrastructure-deployment.md | 44 ++++---- ...privileged-identity-management-requests.md | 28 ++--- docs/release-process.md | 100 ------------------ docs/secrets.md | 23 ++-- 8 files changed, 72 insertions(+), 181 deletions(-) delete mode 100644 docs/docker-hub-credentials.md delete mode 100644 docs/release-process.md diff --git a/docs/connecting-to-azure.md b/docs/connecting-to-azure.md index 6f5937cc68..587db9ce93 100644 --- a/docs/connecting-to-azure.md +++ b/docs/connecting-to-azure.md @@ -52,12 +52,9 @@ but you may need to re-authenticate every once in a while. 4. Then run: ```shell - make review-aks get-cluster-credentials PR_NUMBER=1 + make test-aks get-cluster-credentials ``` - > You can pass in anything as the PR_NUMBER argument for this command; it - > doesn't even need to match a current PR. - 5. Assuming everything worked correctly, you should now be able to access the Kubernetes cluster using the `kubectl` command. @@ -72,10 +69,16 @@ but you may need to re-authenticate every once in a while. ## 2. Get the Kubernetes Deployment name Multiple instances of the app run on the `test` cluster, one for each Pull -Request that has a `deploy` label. Each one is a Kubernetes +Request that has a `deploy` label, plus our `test` app itself. Each one is a +Kubernetes [Deployment](https://kubernetes.io/docs/concepts/workloads/controllers/deployment/) resource. +### Review apps + +Our review apps are under the `srtl-development` namespace within the `test` +cluster. + To connect to a **review app**, the deployment is named after the PR number followed by either web, postgres or worker: @@ -88,15 +91,26 @@ claim-additional-payments-for-teaching-review-[PR_NUMBER]-worker For example, the worker for PR 123 would be `claim-additional-payments-for-teaching-review-123-worker`. -> [!TIP] For a list of all active deployments, run: -> -> ```shell -> kubectl -n srtl-development get deployments -> ``` +For a list of all active review deployments, run: + +```shell +kubectl -n srtl-development get deployments +``` + +### Test app + +Our test app is under the `srtl-test` namespace within the `test` cluster. + +For a list of all test deployments, run: + +```shell +kubectl -n srtl-test get deployments +``` ## 3. Connect to a running container -These commands will connect to a review app. +The following commands will connect to a review app. To connect to the test app, +replace `srtl-development` with `srtl-test` then target the test deployment. ### Open a Rails console diff --git a/docs/developer-onboarding.md b/docs/developer-onboarding.md index b6ff03c459..b22f1dbf0a 100644 --- a/docs/developer-onboarding.md +++ b/docs/developer-onboarding.md @@ -27,7 +27,7 @@ Then, follow these steps to complete your onboarding: 3. Follow the link in the Azure invitation email and create an account. Your password should be no longer than 16 characters. 4. Click on - [this link](https://portal.azure.com/?Microsoft_Azure_PIMCommon=true#blade/Microsoft_AAD_IAM/GroupDetailsMenuBlade/Owners/groupId/6642920a-1aab-49bb-9a20-365131195349) + [this link](https://portal.azure.com/#view/Microsoft_AAD_IAM/GroupDetailsMenuBlade/~/Overview/groupId/f50f3249-db5d-4d96-a123-cd1ef84536c3) – we’ll use this to confirm you’re using the correct directory in Azure. 5. If you see an error about “the group could not be found”, then click on your email address in the top right, choose “Switch directory”, and switch to “DfE @@ -35,9 +35,8 @@ Then, follow these steps to complete your onboarding: 6. If Azure asks you to set up two-factor authentication, see [this advice](#how-to-set-up-azure-two-factor-auth-without-giving-a-phone-number-or-downloading-a-special-app). 7. Ask one of the - [owners](https://portal.azure.com/?Microsoft_Azure_PIMCommon=true#blade/Microsoft_AAD_IAM/GroupDetailsMenuBlade/Owners/groupId/6642920a-1aab-49bb-9a20-365131195349) - of the “s118-teacherpaymentservice-Delivery Team USR” Active Directory group - to follow + [owners](https://portal.azure.com/#view/Microsoft_AAD_IAM/GroupOwnersV3Blade/groupId/f50f3249-db5d-4d96-a123-cd1ef84536c3) + of the “s189 SRTL delivery team” to follow [these instructions](#how-to-add-a-member-to-the-delivery-team-group-in-azure) to add you as a member. 8. Sign up for @@ -113,5 +112,5 @@ proceed. Two-factor auth is now set up. https://portal.azure.com/#blade/Microsoft_AAD_IAM/ActiveDirectoryMenuBlade/Overview. 2. Confirm that it says “DfE Platform Identity” – if not, use the “switch directory” button. -3. In Groups, search for “s118-teacherpaymentservice-Delivery Team USR”. +3. In Groups, search for “s189 SRTL delivery team”. 4. Add the new person. diff --git a/docs/docker-hub-credentials.md b/docs/docker-hub-credentials.md deleted file mode 100644 index e64c19d6cb..0000000000 --- a/docs/docker-hub-credentials.md +++ /dev/null @@ -1,6 +0,0 @@ -# Docker hub - -> Docker hub is managed by Digital tools support and we should talk to them if -> there is any issue - -The credentials are stored in **keyvault** `s118p01-secrets-kv` diff --git a/docs/first-line-support-developer-runbook.md b/docs/first-line-support-developer-runbook.md index d329210892..8c53021d31 100644 --- a/docs/first-line-support-developer-runbook.md +++ b/docs/first-line-support-developer-runbook.md @@ -4,13 +4,6 @@ The audience for this document is a developer working on first-line support, who may not have worked on this service before. It explains how to perform some tasks that you might get asked to do. -## Non-standard things about this project - -- We usually use the word “development” to refer to the `development` - environment in Azure — this is what other projects might call “staging”. To - refer to the application running on a developer’s machine, we usually include - the word “local”, for example “local development”. - ## Support tasks If you want to do one of these tasks and you don’t have what you need, see the diff --git a/docs/infrastructure-deployment.md b/docs/infrastructure-deployment.md index 40222828ba..6f89087889 100644 --- a/docs/infrastructure-deployment.md +++ b/docs/infrastructure-deployment.md @@ -1,47 +1,53 @@ # Deployment process -All of our infrastructure is hosted on DfE's Cloud Infrastructure Platform in -[Microsoft Azure][azure]. +This Rails app runs on the +[Teacher Services Cloud](https://github.com/DFE-Digital/teacher-services-cloud) +Kubernetes infrastructure in Azure. + +All of our infrastructure is run on +[Teacher Services Cloud](https://github.com/DFE-Digital/teacher-services-cloud) +Kubernetes infrastructure in Azure. The setup is specified as [Infrastructure as Code][iac] using Terraform, stored -in the `azure` folder in the root of the project. +in the `terraform` folder in the root of the project. ## Automated deployment -[Azure DevOps](https://dev.azure.com/dfe-ssp/S118-Teacher-Payments-Service) is -responsible for automated infrastructure deployments, this is separate from the -deployment of a version of the application. +We use GitHub Actions to automate our deployments to both the test and +production environments. You can find the workflow +[here](../.github/workflows/build_and_deploy.yml). ## Manual deployment Automated deployment should always be the first option but it may be required to deploy manually for troubleshooting. -### Requesting permissions to acess the infrastructure in higer environments +### Requesting permissions to access the infrastructure in production environments - In the [Azure Portal][azure_portal], navigate to Azure AD Privileged Identity Management. -- Click 'My Roles', then 'Azure Resource Roles'. -- Then click 'Eligible Roles' in the table, choose the role you want access to - and click 'Activate'. +- Click 'My Roles', then 'Groups'. +- In the 'Eligible assignments' table, click 'Activate' on the + `s189 SRTL production PIM` group. - You can then choose how long you want permissions for, enter the reason you - need access and click the button marked 'Activate'. -- Everyone in the Managers group will then get an email saying you have - requested permissions and will be able to grant your permissions. + need access and click the button marked 'Activate' You will need to carry out a Privileged Identity Management request to deploy to -the test or production environments. See +the production environment. See [Privileged Identity Management requests](https://dfedigital.atlassian.net/wiki/spaces/TP/pages/1192624202/Privileged+Identity+Management+requests) for more. ### Deploying to an environment The docker image must be already built. It may be required to create a pull -request to let the build process run. All the available image tags are listed on -DockerHub: https://hub.docker.com/r/dfedigital/teacher-payments-service/tags - -- Verify changes: `make terraform-plan IMAGE_TAG=xyz` -- Apply changes: `make terraform-apply IMAGE_TAG=xyz` +request to let the build process run. All the available image tags are listed in +the GitHub repository packages: +https://github.com/orgs/DFE-Digital/packages?repo_name=claim-additional-payments-for-teaching + +- Verify changes: + `make [production-aks|test-aks] terraform-plan-aks IMAGE_TAG=xyz` +- Apply changes: + `make [production-aks|test-aks] terraform-apply-aks IMAGE_TAG=xyz` [azure]: https://azure.microsoft.com/en-gb/ [iac]: https://en.wikipedia.org/wiki/Infrastructure_as_code diff --git a/docs/privileged-identity-management-requests.md b/docs/privileged-identity-management-requests.md index 87a8232654..a3c5fd3257 100644 --- a/docs/privileged-identity-management-requests.md +++ b/docs/privileged-identity-management-requests.md @@ -1,28 +1,22 @@ # Privileged Identity Management (PIM) requests -Accessing resources in the `production` or `test` environments requires elevated -privileges. We do this through Azure’s Privileged Identity Management (PIM) -request system. +Accessing resources in the production environment requires elevated privileges. +We do this through Azure’s Privileged Identity Management (PIM) request system. To make a PIM request: 1. Visit - [this page](https://portal.azure.com/#blade/Microsoft_Azure_PIMCommon/ActivationMenuBlade/azurerbac). -2. Activate the ‘Contributor’ role for the environment you want to access. + [this page](https://portal.azure.com/#view/Microsoft_Azure_PIMCommon/ActivationMenuBlade/~/aadgroup). +2. Activate the 'Member' role for the `s189 SRTL production PIM` group. 3. Give a reason for your request and submit. -4. The request must now be approved: - - For the `production` environment, you will have to wait until this has been - [approved by another team member](#approving-a-pim-request). - - For `test`, the request is automatically approved. +4. The request must now be approved + [by another team member](#approving-a-pim-request). ## Approving a PIM request -Only -[members](https://portal.azure.com/#blade/Microsoft_AAD_IAM/GroupDetailsMenuBlade/Members/groupId/407a4183-b6a3-4186-a766-9d342935127e) -of the “s118-teacherpaymentservice-Managers USR” Active Directory group can -approve a PIM request. +Only members of the +[s189 SRTL delivery team](https://portal.azure.com/#view/Microsoft_AAD_IAM/GroupDetailsMenuBlade/~/Overview/groupId/f50f3249-db5d-4d96-a123-cd1ef84536c3) +can approve a PIM request. -When somebody makes a PIM request, anyone who can approve it should receive an -email to their `@digital.education.gov.uk` address. If not, they can view all -pending requests -[here](https://portal.azure.com/?Microsoft_Azure_PIMCommon=true#blade/Microsoft_Azure_PIMCommon/ApproveRequestMenuBlade/azurerbac). +You can view all pending requests +[here](https://portal.azure.com/#view/Microsoft_Azure_PIMCommon/ApproveRequestMenuBlade/~/aadmigratedroles). diff --git a/docs/release-process.md b/docs/release-process.md deleted file mode 100644 index 4bc774ca29..0000000000 --- a/docs/release-process.md +++ /dev/null @@ -1,100 +0,0 @@ -# Release Process - -## Get Approval - -Contact the approver and other key stakeholders to obtain approval to release to -production and supply the created release note. - -## Conduct Release - -When releasing code, we take the view that the `master` branch is always -deployable. Whenever we merge a branch into `master`, this is automatically -deployed to our development environment in the DfE Cloud Platform. - -To deploy to production, we take the following steps. - -### 1. Update the Changelog and create a pull request - -- Create a branch from `master` for the release called `release-xxx` where `xxx` - is the release number (a 3 digit number padded with zeros) -- Move all features from the `Unreleased` section of - [`CHANGELOG.md`](../CHANGELOG.md) to a new heading with the release number - linked to a diff of the two latest versions, together with the date in the - following format: - - ```markdown - ## [Release XXX] - 2019-01-01 - - ... - - [release xxx]: - https://github.com/DFE-Digital/dfe-teachers-payment-service/compare/previous-release...release-xxx - ``` - -- Create a commit for the release, including the changes for the release in the - commit message -- Push the branch -- Open a pull request and get it reviewed - -### 2. Confirm the release and review the pull request - -The pull request should be reviewed to confirm that the changes currently in -staging are safe to ship and that [`CHANGELOG.md`](../CHANGELOG.md) accurately -reflects the changes included in the release: - -- Confirm the release with any relevant people (for example the product owner) -- Think about any dependencies that also need considering: dependent parts of - the service that also need updating; environment variables that need - changing/adding; third-party services that need to be set up/updated - -### 3. Testing - -Perform exploratory testing on Azure TEST to ensure the service is working as -expected. - -### 4. Push the tag - -Once the pull request has been merged, create a tag against the merge commit in -the format `release-xxx` (zero-padded again) and push it to GitHub: - -```sh -git tag release-xxx merge-commit-for-release -git push origin refs/tags/release-xxx -``` - -### 5. Trigger a production release in Azure DevOps - -Once the build has passed for the newly tagged commit, you can deploy to -production as follows: - -- Log in to this project on - [Azure DevOps](https://dev.azure.com/dfe-ssp/S118-Teacher-Payments-Service). -- Navigate to Pipelines > Pipelines. -- Find the “Run” which corresponds to the merge commit created by merging the - release pull request into `master`. This is the build which you want to - release. You can filter by branch using the filter / funnel icon in the top - right. -- Note the build number of this build (for example, `20210913.13`). -- Navigate to Pipelines > Releases. -- A release will have been created automatically off the successful build from - master (above) -- The Release will ONLY deploy to DEV automatically -- To deploy to TEST click on the “Deploy Test” button that should have a blue - icon in it. -- The Release will need to be approved to deploy to TEST. -- To deploy to Production click on “Deploy Production” and manually trigger the - deployment by clicking on Deploy in the top menu then Deploy on the Deploy - Release screen -- This deployment will also require approvals. - -### 6. Database Migration - -Follow the -[`guideline`](https://github.com/DFE-Digital/claim-additional-payments-for-teaching/blob/master/README.md#creating-data-migrations) -to run the database migration if required. - -### 7. Announce the release in #claim_early_career_payments_tech - -Post an update in the team's main Slack channel -#claim_early_career_payments_tech to let people know about the new release and -the changes that have just gone out. diff --git a/docs/secrets.md b/docs/secrets.md index 806d8a520f..122c48c2ea 100644 --- a/docs/secrets.md +++ b/docs/secrets.md @@ -3,24 +3,15 @@ ## How to view or change secrets Each environment has its own Azure key vault in a separate resource group to the -main app. The key vaults are behind a firewall and to access them you will need -to add your IP address to the allow list. +main app. -1. If you’re working in the `test` and `production` environments, first elevate - your privileges using a - [PIM request](priviliged-identity-management-requests.md). +1. If you’re working in the `production` environment, first elevate your + privileges using a [PIM request](priviliged-identity-management-requests.md). 2. Navigate to the key vault in the [Azure Portal](https://portal.azure.com): - - `development` – `s118d01-secrets-kv` - - `test` – `s118t01-secrets-kv` - - `production` – `s118p01-secrets-kv` + - `review` – `s189t01-capt-rv-app-kv` + - `test` – `s189t01-capt-ts-app-kv` + - `production` – `s189p01-capt-pd-app-kv` -3. Go to “Firewalls and virtual networks” under Networking. - -4. Add your IP address under Firewall and click Save. - -5. In the key vault, navigate to Secrets to view or change the secrets. - -6. Delete your IP address after you have finished – it will also be - automatically deleted after the next deploy. +3. In the key vault, navigate to Secrets to view or change the secrets. From c1c9cd13cbcdc3226cebb5b40b1a1501a41357a1 Mon Sep 17 00:00:00 2001 From: Richard Lynch Date: Thu, 27 Jun 2024 15:05:53 +0100 Subject: [PATCH 29/66] Fix visiting landing page for same journey Previously if a claimant started a journey then visited the landing page for that journey and choose to continue with their existing session we'd throw an error. The `other_journey_sessions` array contains the journey sessions for the other journeys, which if you're still on the same journey would be empty, so we need to check the current journey session (the session for the journey we're currently on). How we handle managing which journey you're on is subtle and spread across many places in the controllers / concerns, the overall approach likely needs revisiting. --- app/controllers/claims_controller.rb | 6 ++++- spec/features/switching_policies_spec.rb | 30 ++++++++++++++++++++++++ 2 files changed, 35 insertions(+), 1 deletion(-) diff --git a/app/controllers/claims_controller.rb b/app/controllers/claims_controller.rb index 342d3e0a84..42c3917b51 100644 --- a/app/controllers/claims_controller.rb +++ b/app/controllers/claims_controller.rb @@ -39,7 +39,11 @@ def start_new delegate :slugs, :current_slug, :previous_slug, :next_slug, :next_required_slug, to: :page_sequence def redirect_to_existing_claim_journey - new_journey = Journeys.for_routing_name(other_journey_sessions.first.journey) + # If other journey sessions is empty, then the claimant has hit the landing + # page for the journey they're already on, so we need to look at the + # existing session. + other_journey_session = other_journey_sessions.first || journey_session + new_journey = Journeys.for_routing_name(other_journey_session.journey) # Set the params[:journey] to the new journey routing name so things like # journey_session that rely on the journey param find the correct journey. diff --git a/spec/features/switching_policies_spec.rb b/spec/features/switching_policies_spec.rb index 247f207966..0cdd3885a4 100644 --- a/spec/features/switching_policies_spec.rb +++ b/spec/features/switching_policies_spec.rb @@ -95,6 +95,36 @@ end end + context "Switching to the same journey" do + scenario "a user can switch to the same journey after starting a claim on that journey" do + school = create(:school, :combined_journey_eligibile_for_all) + + visit new_claim_path("additional-payments") + + skip_tid + + choose_school school + + expect(page).to have_text( + "Are you currently teaching as a qualified teacher?" + ) + + visit new_claim_path("additional-payments") + + expect(page).to(have_text( + "You have a claim in progress for an additional payment for teaching." + )) + + choose "No, finish the claim I have in progress" + + click_on "Submit" + + expect(page).to have_text( + "Are you currently teaching as a qualified teacher?" + ) + end + end + scenario "a user does not select an option" do start_student_loans_claim visit new_claim_path("additional-payments") From ce134e9d28728f6159d0494ac08ef33a98ebc022 Mon Sep 17 00:00:00 2001 From: Richard Lynch Date: Tue, 25 Jun 2024 14:58:59 +0100 Subject: [PATCH 30/66] Add employment details form Adds the employment details page as per IRP. We've named the fields the same as in IRP. We could probably provide a school search box for this but that's something for a future iteration. Have also added the school details to the PII section to be on the safe side as they might be enough to identify an claimant in combination with some of the other non pii answers. --- .../employment_details_form.rb | 62 +++++++++++ .../get_a_teacher_relocation_payment.rb | 3 +- .../answers_presenter.rb | 59 ++++++++++ .../session_answers.rb | 6 ++ .../slug_sequence.rb | 1 + .../claims/check_your_answers.html.erb | 8 ++ .../claims/employment_details.html.erb | 73 +++++++++++++ config/analytics_blocklist.yml | 6 ++ config/locales/en.yml | 17 +++ ...ional_relocation_payments_eligibilities.rb | 10 ++ db/schema.rb | 8 +- ...et_a_teacher_relocation_payment_answers.rb | 9 ++ .../teacher_route_completing_the_form_spec.rb | 20 ++++ .../employment_details_form_spec.rb | 101 ++++++++++++++++++ .../answers_presenter_spec.rb | 46 ++++++++ .../step_helpers.rb | 28 +++++ 16 files changed, 455 insertions(+), 2 deletions(-) create mode 100644 app/forms/journeys/get_a_teacher_relocation_payment/employment_details_form.rb create mode 100644 app/views/get_a_teacher_relocation_payment/claims/employment_details.html.erb create mode 100644 db/migrate/20240625135618_add_employment_details_to_international_relocation_payments_eligibilities.rb create mode 100644 spec/forms/journeys/get_a_teacher_relocation_payment/employment_details_form_spec.rb diff --git a/app/forms/journeys/get_a_teacher_relocation_payment/employment_details_form.rb b/app/forms/journeys/get_a_teacher_relocation_payment/employment_details_form.rb new file mode 100644 index 0000000000..636472afca --- /dev/null +++ b/app/forms/journeys/get_a_teacher_relocation_payment/employment_details_form.rb @@ -0,0 +1,62 @@ +module Journeys + module GetATeacherRelocationPayment + class EmploymentDetailsForm < Form + attribute :school_headteacher_name, :string + attribute :school_name, :string + attribute :school_address_line_1, :string + attribute :school_address_line_2, :string + attribute :school_city, :string + attribute :school_postcode, :string + + validates :school_headteacher_name, + presence: { + message: i18n_error_message(:school_headteacher_name) + } + + validates :school_name, + presence: { + message: i18n_error_message(:school_name) + } + + validates :school_address_line_1, + presence: { + message: i18n_error_message(:school_address_line_1) + } + + validates :school_city, + presence: { + message: i18n_error_message(:school_city) + } + + validates :school_postcode, + presence: { + message: i18n_error_message(:school_postcode) + } + + validate :school_postcode_is_valid, if: -> { school_postcode.present? } + + def save + return false unless valid? + + journey_session.answers.assign_attributes( + school_headteacher_name: school_headteacher_name, + school_name: school_name, + school_address_line_1: school_address_line_1, + school_address_line_2: school_address_line_2, + school_city: school_city, + school_postcode: school_postcode + ) + + journey_session.save! + end + + private + + def school_postcode_is_valid + unless UKPostcode.parse(school_postcode).full_valid? + errors.add(:school_postcode, i18n_errors_path(:school_postcode)) + end + 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 4a6157eb03..72851e25f9 100644 --- a/app/models/journeys/get_a_teacher_relocation_payment.rb +++ b/app/models/journeys/get_a_teacher_relocation_payment.rb @@ -17,7 +17,8 @@ module GetATeacherRelocationPayment "visa" => VisaForm, "entry-date" => EntryDateForm, "nationality" => NationalityForm, - "passport-number" => PassportNumberForm + "passport-number" => PassportNumberForm, + "employment-details" => EmploymentDetailsForm } } 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 ab1b813591..15bd6c7382 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 @@ -22,6 +22,17 @@ def identity_answers end end + def employment_answers + [].tap do |a| + a << school_headteacher_name + a << school_name + a << school_address_line_1 + a << school_address_line_2 if answers.school_address_line_2.present? + a << school_city + a << school_postcode + end + end + private def application_route @@ -95,6 +106,54 @@ def passport_number "passport-number" ] end + + def school_headteacher_name + [ + t("get_a_teacher_relocation_payment.forms.employment_details.questions.school_headteacher_name"), + answers.school_headteacher_name, + "employment-details" + ] + end + + def school_name + [ + t("get_a_teacher_relocation_payment.forms.employment_details.questions.school_name"), + answers.school_name, + "employment-details" + ] + end + + def school_address_line_1 + [ + t("get_a_teacher_relocation_payment.forms.employment_details.questions.school_address_line_1"), + answers.school_address_line_1, + "employment-details" + ] + end + + def school_address_line_2 + [ + t("get_a_teacher_relocation_payment.forms.employment_details.questions.school_address_line_2"), + answers.school_address_line_2, + "employment-details" + ] + end + + def school_city + [ + t("get_a_teacher_relocation_payment.forms.employment_details.questions.school_city"), + answers.school_city, + "employment-details" + ] + end + + def school_postcode + [ + t("get_a_teacher_relocation_payment.forms.employment_details.questions.school_postcode"), + answers.school_postcode, + "employment-details" + ] + 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 db7ff32547..bd2b9f7fda 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 @@ -10,6 +10,12 @@ class SessionAnswers < Journeys::SessionAnswers attribute :date_of_entry, :date attribute :nationality, :string attribute :passport_number, :string + attribute :school_headteacher_name, :string + attribute :school_name, :string + attribute :school_address_line_1, :string + attribute :school_address_line_2, :string + attribute :school_city, :string + attribute :school_postcode, :string def policy Policies::InternationalRelocationPayments 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 7c7c8e9068..e73418a031 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 @@ -15,6 +15,7 @@ class SlugSequence PERSONAL_DETAILS_SLUGS = [ "nationality", "passport-number", + "employment-details", "personal-details", "postcode-search", "select-home-address", diff --git a/app/views/get_a_teacher_relocation_payment/claims/check_your_answers.html.erb b/app/views/get_a_teacher_relocation_payment/claims/check_your_answers.html.erb index 7ec5c0d37c..b611eb0d72 100644 --- a/app/views/get_a_teacher_relocation_payment/claims/check_your_answers.html.erb +++ b/app/views/get_a_teacher_relocation_payment/claims/check_your_answers.html.erb @@ -23,6 +23,14 @@ } ) %> + <%= render( + partial: "claims/check_your_answers_section", + locals: { + heading: "Employment information", + answers: journey.answers_for_claim(@form.journey_session).employment_answers + } + ) %> + <%= render( partial: "claims/check_your_answers_section", locals: { diff --git a/app/views/get_a_teacher_relocation_payment/claims/employment_details.html.erb b/app/views/get_a_teacher_relocation_payment/claims/employment_details.html.erb new file mode 100644 index 0000000000..069916b530 --- /dev/null +++ b/app/views/get_a_teacher_relocation_payment/claims/employment_details.html.erb @@ -0,0 +1,73 @@ +<% content_for( + :page_title, + page_title( + t("get_a_teacher_relocation_payment.forms.employment_details.title"), + journey: current_journey_routing_name, + show_error: @form.errors.any? + ) +) %> +
+
+

+ <%= t("get_a_teacher_relocation_payment.forms.employment_details.title") %> +

+ + <%= form_for( + @form, + url: claim_path(current_journey_routing_name), + builder: GOVUKDesignSystemFormBuilder::FormBuilder + ) do |f| %> + <%= f.govuk_error_summary %> + + <%= f.govuk_text_field( + :school_headteacher_name, + label: { + text: t("get_a_teacher_relocation_payment.forms.employment_details.questions.school_headteacher_name"), + }, + ) %> + + <%= f.govuk_text_field( + :school_name, + label: { + text: t("get_a_teacher_relocation_payment.forms.employment_details.questions.school_name"), + }, + ) %> + + <%= f.govuk_fieldset( + legend: { + text: t("get_a_teacher_relocation_payment.forms.employment_details.school_address_legend"), + }, + ) do %> + <%= f.govuk_text_field( + :school_address_line_1, + label: { + text: t("get_a_teacher_relocation_payment.forms.employment_details.questions.school_address_line_1"), + }, + ) %> + + <%= f.govuk_text_field( + :school_address_line_2, + label: { + text: t("get_a_teacher_relocation_payment.forms.employment_details.questions.school_address_line_2"), + }, + ) %> + + <%= f.govuk_text_field( + :school_city, + label: { + text: t("get_a_teacher_relocation_payment.forms.employment_details.questions.school_city"), + }, + ) %> + + <%= f.govuk_text_field( + :school_postcode, + label: { + text: t("get_a_teacher_relocation_payment.forms.employment_details.questions.school_postcode"), + }, + ) %> + <% end %> + + <%= f.govuk_submit %> + <% end %> +
+
diff --git a/config/analytics_blocklist.yml b/config/analytics_blocklist.yml index e353302397..ba7e227dd4 100644 --- a/config/analytics_blocklist.yml +++ b/config/analytics_blocklist.yml @@ -98,6 +98,12 @@ - gender_digit :international_relocation_payments_eligibilities: - passport_number + - school_headteacher_name + - school_name + - school_address_line_1 + - school_address_line_2 + - school_city + - school_postcode :levelling_up_premium_payments_eligibilities: - teacher_reference_number :early_career_payments_eligibilities: diff --git a/config/locales/en.yml b/config/locales/en.yml index 91b9a890d1..4952fa96e7 100644 --- a/config/locales/en.yml +++ b/config/locales/en.yml @@ -751,6 +751,23 @@ en: errors: presence: "Enter your passport number" invalid: "Invalid passport number" + employment_details: + title: "Employment information" + school_address_legend: "Enter the school address" + questions: + school_headteacher_name: "Enter the name of the headteacher of the school where you are employed as a teacher" + school_name: "Enter the name of the school" + school_address_line_1: "Address line 1" + school_address_line_2: "Address line 2" + school_city: "Town or city" + school_postcode: "Postcode" + errors: + school_headteacher_name: "Enter the headteacher's name" + school_name: "Enter the school name" + school_address_line_1: "Enter your school's address" + school_city: "Enter your school's city" + school_postcode: "Enter a valid postcode (for example, BN1 1AA)" + check_your_answers: part_one: primary_heading: "Check your answers" diff --git a/db/migrate/20240625135618_add_employment_details_to_international_relocation_payments_eligibilities.rb b/db/migrate/20240625135618_add_employment_details_to_international_relocation_payments_eligibilities.rb new file mode 100644 index 0000000000..6135194908 --- /dev/null +++ b/db/migrate/20240625135618_add_employment_details_to_international_relocation_payments_eligibilities.rb @@ -0,0 +1,10 @@ +class AddEmploymentDetailsToInternationalRelocationPaymentsEligibilities < ActiveRecord::Migration[7.0] + def change + add_column :international_relocation_payments_eligibilities, :school_headteacher_name, :string + add_column :international_relocation_payments_eligibilities, :school_name, :string + add_column :international_relocation_payments_eligibilities, :school_address_line_1, :string + add_column :international_relocation_payments_eligibilities, :school_address_line_2, :string + add_column :international_relocation_payments_eligibilities, :school_city, :string + add_column :international_relocation_payments_eligibilities, :school_postcode, :string + end +end diff --git a/db/schema.rb b/db/schema.rb index 2db075d1f0..8a94175eae 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_24_105924) do +ActiveRecord::Schema[7.0].define(version: 2024_06_25_135618) do # These are extensions that must be enabled in order to support this database enable_extension "pg_trgm" enable_extension "pgcrypto" @@ -199,6 +199,12 @@ t.date "date_of_entry" t.string "nationality" t.string "passport_number" + t.string "school_headteacher_name" + t.string "school_name" + t.string "school_address_line_1" + t.string "school_address_line_2" + t.string "school_city" + t.string "school_postcode" 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 2ebd10b624..fc70a880c8 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 @@ -66,6 +66,15 @@ bank_account_number { rand(10000000..99999999) } end + trait :with_employment_details do + school_headteacher_name { "Seymour Skinner" } + school_name { "Springfield Elementary School" } + school_address_line_1 { "Springfield Elementary School" } + school_address_line_2 { "Plympton Street" } + school_city { "Springfield" } + school_postcode { "TE57 1NG" } + end + trait :eligible_teacher do with_teacher_application_route with_state_funded_secondary_school 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 ab047c414f..c4a62f6ffd 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 @@ -41,6 +41,7 @@ it "submits an application" do and_i_complete_the_nationality_step_with(option: "Australian") and_i_complete_the_passport_number_step_with(options: "123456789") + and_i_complete_the_employment_details_step and_i_complete_the_personal_details_step and_i_complete_the_postcode_step and_i_complete_the_email_address_step @@ -58,6 +59,7 @@ it "submits an application" do and_i_complete_the_nationality_step_with(option: "Australian") and_i_complete_the_passport_number_step_with(options: "123456789") + and_i_complete_the_employment_details_step and_i_complete_the_personal_details_step and_i_complete_the_manual_address_step and_i_complete_the_email_address_step @@ -75,6 +77,7 @@ it "submits an application" do and_i_complete_the_nationality_step_with(option: "Australian") and_i_complete_the_passport_number_step_with(options: "123456789") + and_i_complete_the_employment_details_step and_i_complete_the_personal_details_step and_i_complete_the_manual_address_step and_i_complete_the_email_address_step @@ -92,6 +95,7 @@ it "submits an application" do and_i_complete_the_nationality_step_with(option: "Australian") and_i_complete_the_passport_number_step_with(options: "123456789") + and_i_complete_the_employment_details_step and_i_complete_the_personal_details_step and_i_complete_the_manual_address_step and_i_complete_the_email_address_step @@ -168,6 +172,22 @@ def then_the_check_your_answers_part_page_shows_my_answers(mobile_number: false, "Enter your passport number, as it appears on your passport 123456789" ) + expect(page).to have_text( + "Enter the name of the headteacher of the school where you are employed as a teacher Seymour Skinner" + ) + + expect(page).to have_text( + "Enter the name of the school Springfield Elementary School" + ) + + expect(page).to have_text("Address line 1 Springfield Elementary School") + + expect(page).to have_text("Address line 2 Plympton Street") + + expect(page).to have_text("Town or city Springfield") + + expect(page).to have_text("Postcode TE57 1NG") + if mobile_number expect(page).to have_text("Mobile number 01234567890") else diff --git a/spec/forms/journeys/get_a_teacher_relocation_payment/employment_details_form_spec.rb b/spec/forms/journeys/get_a_teacher_relocation_payment/employment_details_form_spec.rb new file mode 100644 index 0000000000..fd30f27460 --- /dev/null +++ b/spec/forms/journeys/get_a_teacher_relocation_payment/employment_details_form_spec.rb @@ -0,0 +1,101 @@ +require "rails_helper" + +RSpec.describe Journeys::GetATeacherRelocationPayment::EmploymentDetailsForm, type: :model do + let(:journey_session) { create(:get_a_teacher_relocation_payment_session) } + + let(:params) { ActionController::Parameters.new(claim: {}) } + + let(:form) do + described_class.new( + journey_session: journey_session, + journey: Journeys::GetATeacherRelocationPayment, + params: params + ) + end + + describe "validations" do + subject { form } + + it do + is_expected.to( + validate_presence_of(:school_headteacher_name) + .with_message("Enter the headteacher's name") + ) + end + + it do + is_expected.to( + validate_presence_of(:school_name) + .with_message("Enter the school name") + ) + end + + it do + is_expected.to( + validate_presence_of(:school_address_line_1) + .with_message("Enter your school's address") + ) + end + + it do + is_expected.to( + validate_presence_of(:school_city) + .with_message("Enter your school's city") + ) + end + + it do + is_expected.not_to( + allow_value(nil) + .for(:school_postcode) + .with_message("Enter a valid postcode (for example, BN1 1AA)") + ) + end + + it do + is_expected.not_to( + allow_value("fff fff") + .for(:school_postcode) + .with_message("Enter a valid postcode (for example, BN1 1AA)") + ) + end + + it { is_expected.to(allow_value("BN1 1AA").for(:school_postcode)) } + end + + describe "#save" do + let(:params) do + ActionController::Parameters.new(claim: { + school_headteacher_name: "Seymour Skinner", + school_name: "Springfield Elementary School", + school_address_line_1: "19", + school_address_line_2: "Plympton Street", + school_city: "Springfield", + school_postcode: "TE57 1NG" + }) + end + + it "updates the journey session" do + expect { expect(form.save).to be(true) }.to( + change { journey_session.reload.answers.school_headteacher_name } + .to("Seymour Skinner") + .and( + change { journey_session.reload.answers.school_name } + .to("Springfield Elementary School") + ).and( + change { journey_session.reload.answers.school_address_line_1 } + .to("19") + ).and( + change { journey_session.reload.answers.school_address_line_2 } + .to("Plympton Street") + ).and( + change { journey_session.reload.answers.school_city } + .to("Springfield") + ).and( + change { journey_session.reload.answers.school_postcode } + .to("TE57 1NG") + ) + ) + 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 7bf3d90938..54190e5b58 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 @@ -91,4 +91,50 @@ ) end end + + describe "#employment_answers" do + subject { presenter.employment_answers } + + let(:answers) do + build( + :get_a_teacher_relocation_payment_answers, + :with_employment_details + ) + end + + it do + is_expected.to include( + [ + "Enter the name of the headteacher of the school where you are employed as a teacher", + "Seymour Skinner", + "employment-details" + ], + [ + "Enter the name of the school", + "Springfield Elementary School", + "employment-details" + ], + [ + "Address line 1", + "Springfield Elementary School", + "employment-details" + ], + [ + "Address line 2", + "Plympton Street", + "employment-details" + ], + [ + "Town or city", + "Springfield", + "employment-details" + ], + [ + "Postcode", + "TE57 1NG", + "employment-details" + ] + ) + end + end 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 bab9ffeb18..f96384a3bd 100644 --- a/spec/support/get_a_teacher_relocation_payment/step_helpers.rb +++ b/spec/support/get_a_teacher_relocation_payment/step_helpers.rb @@ -93,6 +93,30 @@ def and_i_complete_the_passport_number_step_with(options:) click_button("Continue") end + def and_i_complete_the_employment_details_step + assert_on_employment_details_page! + + fill_in( + "Enter the name of the headteacher of the school where you are employed as a teacher", + with: "Seymour Skinner" + ) + + fill_in( + "Enter the name of the school", + with: "Springfield Elementary School" + ) + + fill_in("Address line 1", with: "Springfield Elementary School") + + fill_in("Address line 2", with: "Plympton Street") + + fill_in("Town or city", with: "Springfield") + + fill_in("Postcode", with: "TE57 1NG") + + click_button("Continue") + end + def and_i_complete_the_personal_details_step assert_on_personal_details_page! @@ -299,6 +323,10 @@ def assert_on_passport_number_page! ) end + def assert_on_employment_details_page! + expect(page).to have_text("Employment information") + end + def assert_on_personal_details_page! expect(page).to have_text("What is your full name?") end From 858dc662f697eb1fd3fa6eccea70bf3a17e32e02 Mon Sep 17 00:00:00 2001 From: Richard Lynch Date: Wed, 26 Jun 2024 14:49:12 +0100 Subject: [PATCH 31/66] Remove TRN step We don't want to ask for a TRN on the IRP journey. We previously asked for it as it was required to submit a claim. Now TRN is no longer a required field on the claim we can drop the TRN step from the IRP journey. --- .../get_a_teacher_relocation_payment/answers_presenter.rb | 4 ++++ .../get_a_teacher_relocation_payment/slug_sequence.rb | 3 +-- .../teacher_route_completing_the_form_spec.rb | 4 ---- .../get_a_teacher_relocation_payment/step_helpers.rb | 8 -------- 4 files changed, 5 insertions(+), 14 deletions(-) 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 15bd6c7382..b4ad7fe7f7 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 @@ -35,6 +35,10 @@ def employment_answers private + def show_trn? + false + end + def application_route [ t("get_a_teacher_relocation_payment.forms.application_route.question"), 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 e73418a031..70bb70d24d 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 @@ -31,8 +31,7 @@ class SlugSequence "bank-or-building-society", "personal-bank-account", "building-society-account", - "gender", - "teacher-reference-number" + "gender" ].freeze RESULTS_SLUGS = [ 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 c4a62f6ffd..c8fb070648 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 @@ -48,7 +48,6 @@ and_i_dont_provide_my_mobile_number and_i_provide_my_personal_bank_details and_i_complete_the_payroll_gender_step - and_i_complete_the_trn_step then_the_check_your_answers_part_page_shows_my_answers and_i_submit_the_application then_the_application_is_submitted_successfully @@ -66,7 +65,6 @@ and_i_dont_provide_my_mobile_number and_i_provide_my_personal_bank_details and_i_complete_the_payroll_gender_step - and_i_complete_the_trn_step then_the_check_your_answers_part_page_shows_my_answers and_i_submit_the_application then_the_application_is_submitted_successfully @@ -84,7 +82,6 @@ and_i_provide_my_mobile_number and_i_provide_my_personal_bank_details and_i_complete_the_payroll_gender_step - and_i_complete_the_trn_step then_the_check_your_answers_part_page_shows_my_answers(mobile_number: true) and_i_submit_the_application then_the_application_is_submitted_successfully @@ -102,7 +99,6 @@ and_i_provide_my_mobile_number and_i_provide_my_building_society_details and_i_complete_the_payroll_gender_step - and_i_complete_the_trn_step then_the_check_your_answers_part_page_shows_my_answers( mobile_number: true, building_society: true 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 f96384a3bd..06c9234728 100644 --- a/spec/support/get_a_teacher_relocation_payment/step_helpers.rb +++ b/spec/support/get_a_teacher_relocation_payment/step_helpers.rb @@ -263,14 +263,6 @@ def and_i_complete_the_payroll_gender_step click_button("Continue") end - # FIXME RL: Once https://dfedigital.atlassian.net.mcas.ms/browse/CAPT-1625 - # remove this step. We don't want to capture a TRN on the IRP journey. - def and_i_complete_the_trn_step - fill_in("What is your teacher reference number (TRN)?", with: "1234567") - - click_button("Continue") - end - def then_the_application_is_submitted_successfully assert_application_is_submitted! end From 2e95b885f8c09c04d4cb2acb56848d04e1ea80cf Mon Sep 17 00:00:00 2001 From: Richard Lynch Date: Tue, 25 Jun 2024 15:15:51 +0100 Subject: [PATCH 32/66] Add smoke test Adds a smoke test to ensure the expect attributes for the journey are written to the claim and eligibility. --- .../claim_submission_form_spec.rb | 97 +++++++++++++++++++ 1 file changed, 97 insertions(+) create mode 100644 spec/forms/journeys/get_a_teacher_relocation_payment/claim_submission_form_spec.rb diff --git a/spec/forms/journeys/get_a_teacher_relocation_payment/claim_submission_form_spec.rb b/spec/forms/journeys/get_a_teacher_relocation_payment/claim_submission_form_spec.rb new file mode 100644 index 0000000000..dbee398f69 --- /dev/null +++ b/spec/forms/journeys/get_a_teacher_relocation_payment/claim_submission_form_spec.rb @@ -0,0 +1,97 @@ +require "rails_helper" + +RSpec.describe Journeys::GetATeacherRelocationPayment::ClaimSubmissionForm do + let(:journey_configuration) do + create(:journey_configuration, :get_a_teacher_relocation_payment) + end + + let(:claim_answers) do + { + address_line_1: "330", + address_line_2: "Pikeland Ave", + address_line_3: "Springfield", + address_line_4: "Oregon", + postcode: "TE57 1NG", + date_of_birth: Date.new(1944, 7, 12), + national_insurance_number: "AB123456C", + email_address: "seymour-skinner@springfield-elementy.edu", + bank_sort_code: "123456", + bank_account_number: "12345678", + details_check: true, + payroll_gender: "male", + first_name: "Seymour", + middle_name: "Walter", + surname: "Skinner", + banking_name: "Seymour W Skinner", + building_society_roll_number: "12345678", + academic_year: journey_configuration.current_academic_year.to_s, + bank_or_building_society: "personal_bank_account", + provide_mobile_number: true, + mobile_number: "07123456789", + email_verified: true, + mobile_verified: true, + hmrc_bank_validation_succeeded: true, + hmrc_bank_validation_responses: {} + } + end + + let(:start_date) { Date.tomorrow } + + let(:eligibility_answers) do + { + application_route: "teacher", + state_funded_secondary_school: true, + one_year: true, + start_date: start_date, + subject: "physics", + visa_type: "British National (Overseas) visa", + date_of_entry: start_date - 1.week, + nationality: "Australian", + passport_number: "1234567890123456789A", + school_headteacher_name: "Seymour Skinner", + school_name: "Springfield Elementary School", + school_address_line_1: "Springfield Elementary School", + school_address_line_2: "Plympton Street", + school_city: "Springfield", + school_postcode: "TE57 1NG" + } + end + + let(:journey_session) do + create( + :get_a_teacher_relocation_payment_session, + answers: answers + ) + end + + let(:form) { described_class.new(journey_session: journey_session) } + + describe "#save" do + let(:answers) do + build( + :get_a_teacher_relocation_payment_answers, + **claim_answers.merge(eligibility_answers) + ) + end + + before { form.save } + + it "sets the expect attributes on the claim" do + claim = form.claim + + eligibility = claim.eligibility + + claim_answers.each do |attribute, value| + expect(claim.public_send(attribute)).to eq(value) + end + + expect(claim.submitted_at).to be_present + + expect(claim.reference).to be_present + + eligibility_answers.each do |attribute, value| + expect(eligibility.public_send(attribute)).to eq(value) + end + end + end +end From f233d5fbbc2888a5e482a4fb9062f132be9fc506 Mon Sep 17 00:00:00 2001 From: Richard Lynch Date: Tue, 25 Jun 2024 16:01:06 +0100 Subject: [PATCH 33/66] Remove shared/error summary Rendering errors is built into govuk form builder so we should use that rather than rendering the shared partial. --- .../claims/application_route.html.erb | 4 +--- .../claims/contract_details.html.erb | 4 +--- .../claims/entry_date.html.erb | 4 +--- .../claims/start_date.html.erb | 4 +--- .../claims/state_funded_secondary_school.html.erb | 4 +--- .../get_a_teacher_relocation_payment/claims/subject.html.erb | 4 +--- .../get_a_teacher_relocation_payment/claims/visa.html.erb | 4 +--- 7 files changed, 7 insertions(+), 21 deletions(-) diff --git a/app/views/get_a_teacher_relocation_payment/claims/application_route.html.erb b/app/views/get_a_teacher_relocation_payment/claims/application_route.html.erb index edbf0598e6..f884131bd5 100644 --- a/app/views/get_a_teacher_relocation_payment/claims/application_route.html.erb +++ b/app/views/get_a_teacher_relocation_payment/claims/application_route.html.erb @@ -13,9 +13,7 @@ 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_error_summary %> <%= f.govuk_collection_radio_buttons( :application_route, diff --git a/app/views/get_a_teacher_relocation_payment/claims/contract_details.html.erb b/app/views/get_a_teacher_relocation_payment/claims/contract_details.html.erb index be7a3908c3..4b8d5fd081 100644 --- a/app/views/get_a_teacher_relocation_payment/claims/contract_details.html.erb +++ b/app/views/get_a_teacher_relocation_payment/claims/contract_details.html.erb @@ -13,9 +13,7 @@ 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_error_summary %> <%= f.govuk_collection_radio_buttons( :one_year, 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 index 53ed14387d..74f6bf28a1 100644 --- 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 @@ -13,9 +13,7 @@ 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_error_summary %> <%= f.govuk_date_field( :date_of_entry, diff --git a/app/views/get_a_teacher_relocation_payment/claims/start_date.html.erb b/app/views/get_a_teacher_relocation_payment/claims/start_date.html.erb index 8b5e94c191..f3f6683dd9 100644 --- a/app/views/get_a_teacher_relocation_payment/claims/start_date.html.erb +++ b/app/views/get_a_teacher_relocation_payment/claims/start_date.html.erb @@ -13,9 +13,7 @@ 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_error_summary %> <%= f.govuk_date_field( :start_date, diff --git a/app/views/get_a_teacher_relocation_payment/claims/state_funded_secondary_school.html.erb b/app/views/get_a_teacher_relocation_payment/claims/state_funded_secondary_school.html.erb index a3869070d6..98e57ac2f6 100644 --- a/app/views/get_a_teacher_relocation_payment/claims/state_funded_secondary_school.html.erb +++ b/app/views/get_a_teacher_relocation_payment/claims/state_funded_secondary_school.html.erb @@ -13,9 +13,7 @@ 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_error_summary %> <%= f.govuk_collection_radio_buttons( :state_funded_secondary_school, diff --git a/app/views/get_a_teacher_relocation_payment/claims/subject.html.erb b/app/views/get_a_teacher_relocation_payment/claims/subject.html.erb index 48be6db057..6e6cb34899 100644 --- a/app/views/get_a_teacher_relocation_payment/claims/subject.html.erb +++ b/app/views/get_a_teacher_relocation_payment/claims/subject.html.erb @@ -13,9 +13,7 @@ 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_error_summary %> <%= f.govuk_collection_radio_buttons( :subject, diff --git a/app/views/get_a_teacher_relocation_payment/claims/visa.html.erb b/app/views/get_a_teacher_relocation_payment/claims/visa.html.erb index 5b274bc5d4..c214f866bb 100644 --- a/app/views/get_a_teacher_relocation_payment/claims/visa.html.erb +++ b/app/views/get_a_teacher_relocation_payment/claims/visa.html.erb @@ -13,9 +13,7 @@ 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_error_summary %> <%= f.govuk_collection_select( :visa_type, From cbff8362c9a311cab7c05a36c64d971308ab21f5 Mon Sep 17 00:00:00 2001 From: Richard Lynch Date: Tue, 25 Jun 2024 16:11:00 +0100 Subject: [PATCH 34/66] Fix forms Updates the forms to show large legends and set the legend to a H1 where it is acting as the page title. --- .../claims/application_route.html.erb | 6 +++++- .../claims/contract_details.html.erb | 6 +++++- .../claims/entry_date.html.erb | 4 +++- .../claims/nationality.html.erb | 3 ++- .../claims/passport_number.html.erb | 3 ++- .../claims/start_date.html.erb | 6 +++++- .../claims/state_funded_secondary_school.html.erb | 6 +++++- .../claims/subject.html.erb | 6 +++++- .../get_a_teacher_relocation_payment/claims/visa.html.erb | 3 ++- 9 files changed, 34 insertions(+), 9 deletions(-) diff --git a/app/views/get_a_teacher_relocation_payment/claims/application_route.html.erb b/app/views/get_a_teacher_relocation_payment/claims/application_route.html.erb index f884131bd5..6fb432e988 100644 --- a/app/views/get_a_teacher_relocation_payment/claims/application_route.html.erb +++ b/app/views/get_a_teacher_relocation_payment/claims/application_route.html.erb @@ -25,7 +25,11 @@ t("get_a_teacher_relocation_payment.forms.application_route.answers.#{option}.hint") end end, - legend: { text: t("get_a_teacher_relocation_payment.forms.application_route.question") }, + legend: { + text: t("get_a_teacher_relocation_payment.forms.application_route.question"), + size: "l", + tag: "h1" + }, hint: { text: t("get_a_teacher_relocation_payment.forms.application_route.hint") } ) %> diff --git a/app/views/get_a_teacher_relocation_payment/claims/contract_details.html.erb b/app/views/get_a_teacher_relocation_payment/claims/contract_details.html.erb index 4b8d5fd081..b9b23ab18c 100644 --- a/app/views/get_a_teacher_relocation_payment/claims/contract_details.html.erb +++ b/app/views/get_a_teacher_relocation_payment/claims/contract_details.html.erb @@ -20,7 +20,11 @@ f.object.available_options, -> (option) { option }, -> (option) { t("get_a_teacher_relocation_payment.forms.contract_details.answers.#{option}.answer") }, - legend: { text: t("get_a_teacher_relocation_payment.forms.contract_details.question") }, + legend: { + text: t("get_a_teacher_relocation_payment.forms.contract_details.question"), + size: "l", + tag: "h1" + }, hint: { text: t("get_a_teacher_relocation_payment.forms.contract_details.hint") } ) %> 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 index 74f6bf28a1..de33b65e9d 100644 --- 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 @@ -18,7 +18,9 @@ <%= f.govuk_date_field( :date_of_entry, legend: { - text: t("get_a_teacher_relocation_payment.forms.entry_date.question") + text: t("get_a_teacher_relocation_payment.forms.entry_date.question"), + size: "l", + tag: "h1" }, ) %> diff --git a/app/views/get_a_teacher_relocation_payment/claims/nationality.html.erb b/app/views/get_a_teacher_relocation_payment/claims/nationality.html.erb index e883629979..2a74451fe1 100644 --- a/app/views/get_a_teacher_relocation_payment/claims/nationality.html.erb +++ b/app/views/get_a_teacher_relocation_payment/claims/nationality.html.erb @@ -22,7 +22,8 @@ :to_s, label: { text: t("get_a_teacher_relocation_payment.forms.nationality.question"), - size: "l" + size: "l", + tag: "h1" }, options: { include_blank: true diff --git a/app/views/get_a_teacher_relocation_payment/claims/passport_number.html.erb b/app/views/get_a_teacher_relocation_payment/claims/passport_number.html.erb index 4c2b540106..134217d2c6 100644 --- a/app/views/get_a_teacher_relocation_payment/claims/passport_number.html.erb +++ b/app/views/get_a_teacher_relocation_payment/claims/passport_number.html.erb @@ -19,7 +19,8 @@ :passport_number, label: { text: t("get_a_teacher_relocation_payment.forms.passport_number.question"), - size: "l" + size: "l", + tag: "h1" }, ) %> diff --git a/app/views/get_a_teacher_relocation_payment/claims/start_date.html.erb b/app/views/get_a_teacher_relocation_payment/claims/start_date.html.erb index f3f6683dd9..bf2cd2c69c 100644 --- a/app/views/get_a_teacher_relocation_payment/claims/start_date.html.erb +++ b/app/views/get_a_teacher_relocation_payment/claims/start_date.html.erb @@ -17,7 +17,11 @@ <%= f.govuk_date_field( :start_date, - legend: { text: t("get_a_teacher_relocation_payment.forms.start_date.question") }, + legend: { + text: t("get_a_teacher_relocation_payment.forms.start_date.question"), + size: "l", + tag: "h1" + }, ) %> <%= f.govuk_submit %> diff --git a/app/views/get_a_teacher_relocation_payment/claims/state_funded_secondary_school.html.erb b/app/views/get_a_teacher_relocation_payment/claims/state_funded_secondary_school.html.erb index 98e57ac2f6..d3797339d5 100644 --- a/app/views/get_a_teacher_relocation_payment/claims/state_funded_secondary_school.html.erb +++ b/app/views/get_a_teacher_relocation_payment/claims/state_funded_secondary_school.html.erb @@ -20,7 +20,11 @@ f.object.available_options, -> (option) { option }, -> (option) { t("get_a_teacher_relocation_payment.forms.state_funded_secondary_school.answers.#{option}.answer") }, - legend: { text: t("get_a_teacher_relocation_payment.forms.state_funded_secondary_school.question") }, + legend: { + text: t("get_a_teacher_relocation_payment.forms.state_funded_secondary_school.question"), + size: "l", + tag: "h1" + }, hint: { text: t("get_a_teacher_relocation_payment.forms.state_funded_secondary_school.hint") } ) %> diff --git a/app/views/get_a_teacher_relocation_payment/claims/subject.html.erb b/app/views/get_a_teacher_relocation_payment/claims/subject.html.erb index 6e6cb34899..4f33f90c6c 100644 --- a/app/views/get_a_teacher_relocation_payment/claims/subject.html.erb +++ b/app/views/get_a_teacher_relocation_payment/claims/subject.html.erb @@ -20,7 +20,11 @@ f.object.available_options, -> (option) { option }, -> (option) { t("get_a_teacher_relocation_payment.forms.subject.answers.#{option}") }, - legend: { text: t("get_a_teacher_relocation_payment.forms.subject.question") }, + legend: { + text: t("get_a_teacher_relocation_payment.forms.subject.question"), + size: "l", + tag: "h1" + }, hint: { text: t("get_a_teacher_relocation_payment.forms.subject.hint") } ) %> diff --git a/app/views/get_a_teacher_relocation_payment/claims/visa.html.erb b/app/views/get_a_teacher_relocation_payment/claims/visa.html.erb index c214f866bb..d7b44722cb 100644 --- a/app/views/get_a_teacher_relocation_payment/claims/visa.html.erb +++ b/app/views/get_a_teacher_relocation_payment/claims/visa.html.erb @@ -22,7 +22,8 @@ :to_s, label: { text: t("get_a_teacher_relocation_payment.forms.visa.question"), - size: "m" + size: "l", + tag: "h1" }, options: { include_blank: true From f4932eff086a8ffa410d35eed862d3a05a6b9e68 Mon Sep 17 00:00:00 2001 From: Richard Lynch Date: Wed, 26 Jun 2024 15:47:03 +0100 Subject: [PATCH 35/66] Don't allow future dates for start date IRP feedback from Richard Forrest > I am able to enter a contract start date in the future although I can't > enter a travel date in the future. Can both these fields only accept > dates in the past? Updates the start date form to not permit dates in the future. --- .../start_date_form.rb | 8 ++++++- config/locales/en.yml | 1 + .../teacher_route_completing_the_form_spec.rb | 2 +- .../start_date_form_spec.rb | 24 +++++++++---------- 4 files changed, 21 insertions(+), 14 deletions(-) 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 517ea0d99e..c391b86a4d 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 @@ -3,12 +3,18 @@ module GetATeacherRelocationPayment class StartDateForm < Form include ActiveRecord::AttributeAssignment + attribute :start_date, :date + validates :start_date, presence: { message: i18n_error_message(:presence) } - attribute :start_date, :date + validates :start_date, + comparison: { + less_than: ->(_) { Date.tomorrow }, + message: i18n_error_message(:date_not_in_future) + }, if: :start_date def initialize(journey_session:, journey:, params:) super diff --git a/config/locales/en.yml b/config/locales/en.yml index 4952fa96e7..1c9fb284fc 100644 --- a/config/locales/en.yml +++ b/config/locales/en.yml @@ -723,6 +723,7 @@ en: question: "Enter the start date of your contract" errors: presence: "Enter your contract start date" + date_not_in_future: "Start date cannot be in the future" subject: question: "What subject are you employed to teach at your school?" hint: "Physics, general or combined science including physics, and languages can be combined with other subjects but must make up at least 50% of your time in the classroom." 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 c8fb070648..26fc3916a9 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 @@ -8,7 +8,7 @@ end let(:contract_start_date) do - Date.tomorrow + Date.yesterday end let(:entry_date) do 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 b5419c2725..de82e23aff 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 @@ -9,6 +9,8 @@ ) end + let(:option) { nil } + def multi_part_date_parms(date) return {} unless date.present? @@ -31,27 +33,25 @@ def multi_part_date_parms(date) subject { form } context "with an invalid date" do - let(:option) { nil } - it { is_expected.not_to be_valid } end context "with a date in the future" do - let(:option) { Date.tomorrow } - - it { is_expected.to be_valid } + it do + is_expected.not_to( + allow_value(Date.tomorrow) + .for(:start_date) + .with_message("Start date cannot be in the future") + ) + end end context "with a date in the present" do - let(:option) { Date.today } - - it { is_expected.to be_valid } + it { is_expected.to allow_value(Date.today).for(:start_date) } end context "with a date in the past" do - let(:option) { Date.yesterday } - - it { is_expected.to be_valid } + it { is_expected.to allow_value(Date.yesterday).for(:start_date) } end end @@ -90,7 +90,7 @@ def multi_part_date_parms(date) end describe "#save" do - let(:option) { Date.tomorrow } + let(:option) { Date.yesterday } it "updates the journey session" do expect { expect(form.save).to be(true) }.to( From 6514a04ce7da044c15df63689ddb4774f9fe3fd0 Mon Sep 17 00:00:00 2001 From: Phil Lee Date: Thu, 27 Jun 2024 12:54:15 +0100 Subject: [PATCH 36/66] GIAS import also stores UKPRN --- app/models/school_data_importer.rb | 1 + config/analytics.yml | 1 + db/migrate/20240627114644_add_ukprn_to_schools.rb | 7 +++++++ db/schema.rb | 4 +++- spec/{services => models}/school_data_importer_spec.rb | 1 + 5 files changed, 13 insertions(+), 1 deletion(-) create mode 100644 db/migrate/20240627114644_add_ukprn_to_schools.rb rename spec/{services => models}/school_data_importer_spec.rb (98%) diff --git a/app/models/school_data_importer.rb b/app/models/school_data_importer.rb index de788a2a96..7ea1026c49 100644 --- a/app/models/school_data_importer.rb +++ b/app/models/school_data_importer.rb @@ -46,6 +46,7 @@ def row_to_school(row) school.statutory_high_age = row.fetch("StatutoryHighAge") school.phone_number = row.fetch("TelephoneNum") school.open_date = row.fetch("OpenDate") + school.ukprn = row.fetch("UKPRN") school end end diff --git a/config/analytics.yml b/config/analytics.yml index 1f02b9d51d..1584ca664f 100644 --- a/config/analytics.yml +++ b/config/analytics.yml @@ -221,6 +221,7 @@ shared: - statutory_high_age - phone_number - open_date + - ukprn :support_tickets: - id - url diff --git a/db/migrate/20240627114644_add_ukprn_to_schools.rb b/db/migrate/20240627114644_add_ukprn_to_schools.rb new file mode 100644 index 0000000000..51836d23e1 --- /dev/null +++ b/db/migrate/20240627114644_add_ukprn_to_schools.rb @@ -0,0 +1,7 @@ +class AddUkprnToSchools < ActiveRecord::Migration[7.0] + def change + add_column :schools, :ukprn, :text, null: true + + add_index :schools, :ukprn + end +end diff --git a/db/schema.rb b/db/schema.rb index 8a94175eae..f63cb06b77 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_25_135618) do +ActiveRecord::Schema[7.0].define(version: 2024_06_27_114644) do # These are extensions that must be enabled in order to support this database enable_extension "pg_trgm" enable_extension "pgcrypto" @@ -374,6 +374,7 @@ t.string "phone_number", limit: 20 t.date "open_date" t.string "postcode_sanitised" + t.text "ukprn" t.index ["close_date"], name: "index_schools_on_close_date" t.index ["created_at"], name: "index_schools_on_created_at" t.index ["local_authority_district_id"], name: "index_schools_on_local_authority_district_id" @@ -381,6 +382,7 @@ t.index ["name"], name: "index_schools_on_name", opclass: :gin_trgm_ops, using: :gin t.index ["open_date"], name: "index_schools_on_open_date" t.index ["postcode_sanitised"], name: "index_schools_on_postcode_sanitised", opclass: :gin_trgm_ops, using: :gin + t.index ["ukprn"], name: "index_schools_on_ukprn" t.index ["urn"], name: "index_schools_on_urn", unique: true end diff --git a/spec/services/school_data_importer_spec.rb b/spec/models/school_data_importer_spec.rb similarity index 98% rename from spec/services/school_data_importer_spec.rb rename to spec/models/school_data_importer_spec.rb index f350297eda..54e24168ac 100644 --- a/spec/services/school_data_importer_spec.rb +++ b/spec/models/school_data_importer_spec.rb @@ -44,6 +44,7 @@ expect(imported_school.statutory_high_age).to eq(18) expect(imported_school.phone_number).to eq("01226762114") expect(imported_school.open_date).to be_nil + expect(imported_school.ukprn).to eql("10005034") end it "imports a closed school with the date it closed" do From 4a12f1a68109afd94f8f4c4f522330e10a408f57 Mon Sep 17 00:00:00 2001 From: Richard Lynch Date: Thu, 27 Jun 2024 13:28:46 +0100 Subject: [PATCH 37/66] Replace employment details with select school In the original IRP journey the claimant had to manually enter their school's address. We've replaced manual address entering with a school select form. We still ask for the name of the head teacher as the GIAS database doesn't contain head teacher information for all schools. --- .../employment_details_form.rb | 62 ----------- .../headteacher_details_form.rb | 22 ++++ .../get_a_teacher_relocation_payment.rb | 2 +- .../answers_presenter.rb | 54 ++-------- .../session_answers.rb | 5 - .../slug_sequence.rb | 3 +- .../claims/_current_school_details.html.erb | 1 + .../claims/_current_school_question.html.erb | 3 + ...nt_school_search_results_question.html.erb | 5 + .../claims/employment_details.html.erb | 73 ------------- .../claims/headteacher_details.html.erb | 30 ++++++ config/analytics.yml | 1 + config/analytics_blocklist.yml | 5 - config/locales/en.yml | 17 +-- ..._from_international_relocation_payments.rb | 9 ++ ...ional_relocation_payments_eligibilities.rb | 11 ++ db/schema.rb | 10 +- ...et_a_teacher_relocation_payment_answers.rb | 6 +- .../teacher_route_completing_the_form_spec.rb | 37 +++---- .../claim_submission_form_spec.rb | 6 +- .../employment_details_form_spec.rb | 101 ------------------ .../headteacher_details_form_spec.rb | 41 +++++++ .../answers_presenter_spec.rb | 32 ++---- .../step_helpers.rb | 38 ++++--- 24 files changed, 195 insertions(+), 379 deletions(-) delete mode 100644 app/forms/journeys/get_a_teacher_relocation_payment/employment_details_form.rb create mode 100644 app/forms/journeys/get_a_teacher_relocation_payment/headteacher_details_form.rb create mode 100644 app/views/get_a_teacher_relocation_payment/claims/_current_school_details.html.erb create mode 100644 app/views/get_a_teacher_relocation_payment/claims/_current_school_question.html.erb create mode 100644 app/views/get_a_teacher_relocation_payment/claims/_current_school_search_results_question.html.erb delete mode 100644 app/views/get_a_teacher_relocation_payment/claims/employment_details.html.erb create mode 100644 app/views/get_a_teacher_relocation_payment/claims/headteacher_details.html.erb create mode 100644 db/migrate/20240627121651_drop_eligibility_columns_from_international_relocation_payments.rb create mode 100644 db/migrate/20240627145713_add_current_school_id_to_international_relocation_payments_eligibilities.rb delete mode 100644 spec/forms/journeys/get_a_teacher_relocation_payment/employment_details_form_spec.rb create mode 100644 spec/forms/journeys/get_a_teacher_relocation_payment/headteacher_details_form_spec.rb diff --git a/app/forms/journeys/get_a_teacher_relocation_payment/employment_details_form.rb b/app/forms/journeys/get_a_teacher_relocation_payment/employment_details_form.rb deleted file mode 100644 index 636472afca..0000000000 --- a/app/forms/journeys/get_a_teacher_relocation_payment/employment_details_form.rb +++ /dev/null @@ -1,62 +0,0 @@ -module Journeys - module GetATeacherRelocationPayment - class EmploymentDetailsForm < Form - attribute :school_headteacher_name, :string - attribute :school_name, :string - attribute :school_address_line_1, :string - attribute :school_address_line_2, :string - attribute :school_city, :string - attribute :school_postcode, :string - - validates :school_headteacher_name, - presence: { - message: i18n_error_message(:school_headteacher_name) - } - - validates :school_name, - presence: { - message: i18n_error_message(:school_name) - } - - validates :school_address_line_1, - presence: { - message: i18n_error_message(:school_address_line_1) - } - - validates :school_city, - presence: { - message: i18n_error_message(:school_city) - } - - validates :school_postcode, - presence: { - message: i18n_error_message(:school_postcode) - } - - validate :school_postcode_is_valid, if: -> { school_postcode.present? } - - def save - return false unless valid? - - journey_session.answers.assign_attributes( - school_headteacher_name: school_headteacher_name, - school_name: school_name, - school_address_line_1: school_address_line_1, - school_address_line_2: school_address_line_2, - school_city: school_city, - school_postcode: school_postcode - ) - - journey_session.save! - end - - private - - def school_postcode_is_valid - unless UKPostcode.parse(school_postcode).full_valid? - errors.add(:school_postcode, i18n_errors_path(:school_postcode)) - end - end - end - end -end diff --git a/app/forms/journeys/get_a_teacher_relocation_payment/headteacher_details_form.rb b/app/forms/journeys/get_a_teacher_relocation_payment/headteacher_details_form.rb new file mode 100644 index 0000000000..ca1b123c1f --- /dev/null +++ b/app/forms/journeys/get_a_teacher_relocation_payment/headteacher_details_form.rb @@ -0,0 +1,22 @@ +module Journeys + module GetATeacherRelocationPayment + class HeadteacherDetailsForm < Form + attribute :school_headteacher_name, :string + + validates :school_headteacher_name, + presence: { + message: i18n_error_message(:school_headteacher_name) + } + + def save + return false unless valid? + + journey_session.answers.assign_attributes( + school_headteacher_name: school_headteacher_name + ) + + journey_session.save! + 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 72851e25f9..37e9b48739 100644 --- a/app/models/journeys/get_a_teacher_relocation_payment.rb +++ b/app/models/journeys/get_a_teacher_relocation_payment.rb @@ -18,7 +18,7 @@ module GetATeacherRelocationPayment "entry-date" => EntryDateForm, "nationality" => NationalityForm, "passport-number" => PassportNumberForm, - "employment-details" => EmploymentDetailsForm + "headteacher-details" => HeadteacherDetailsForm } } 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 b4ad7fe7f7..7d7a51eed6 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 @@ -24,12 +24,8 @@ def identity_answers def employment_answers [].tap do |a| + a << current_school a << school_headteacher_name - a << school_name - a << school_address_line_1 - a << school_address_line_2 if answers.school_address_line_2.present? - a << school_city - a << school_postcode end end @@ -111,51 +107,19 @@ def passport_number ] end - def school_headteacher_name - [ - t("get_a_teacher_relocation_payment.forms.employment_details.questions.school_headteacher_name"), - answers.school_headteacher_name, - "employment-details" - ] - end - - def school_name - [ - t("get_a_teacher_relocation_payment.forms.employment_details.questions.school_name"), - answers.school_name, - "employment-details" - ] - end - - def school_address_line_1 + def current_school [ - t("get_a_teacher_relocation_payment.forms.employment_details.questions.school_address_line_1"), - answers.school_address_line_1, - "employment-details" + t("get_a_teacher_relocation_payment.forms.current_school.questions.current_school_search"), + answers.current_school.name, + "current-school" ] end - def school_address_line_2 - [ - t("get_a_teacher_relocation_payment.forms.employment_details.questions.school_address_line_2"), - answers.school_address_line_2, - "employment-details" - ] - end - - def school_city - [ - t("get_a_teacher_relocation_payment.forms.employment_details.questions.school_city"), - answers.school_city, - "employment-details" - ] - end - - def school_postcode + def school_headteacher_name [ - t("get_a_teacher_relocation_payment.forms.employment_details.questions.school_postcode"), - answers.school_postcode, - "employment-details" + t("get_a_teacher_relocation_payment.forms.headteacher_details.questions.school_headteacher_name"), + answers.school_headteacher_name, + "headteacher-details" ] 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 bd2b9f7fda..0857455b63 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 @@ -11,11 +11,6 @@ class SessionAnswers < Journeys::SessionAnswers attribute :nationality, :string attribute :passport_number, :string attribute :school_headteacher_name, :string - attribute :school_name, :string - attribute :school_address_line_1, :string - attribute :school_address_line_2, :string - attribute :school_city, :string - attribute :school_postcode, :string def policy Policies::InternationalRelocationPayments 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 70bb70d24d..d38bca9d7e 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 @@ -15,7 +15,8 @@ class SlugSequence PERSONAL_DETAILS_SLUGS = [ "nationality", "passport-number", - "employment-details", + "current-school", + "headteacher-details", "personal-details", "postcode-search", "select-home-address", diff --git a/app/views/get_a_teacher_relocation_payment/claims/_current_school_details.html.erb b/app/views/get_a_teacher_relocation_payment/claims/_current_school_details.html.erb new file mode 100644 index 0000000000..8e213d7645 --- /dev/null +++ b/app/views/get_a_teacher_relocation_payment/claims/_current_school_details.html.erb @@ -0,0 +1 @@ +<%# NOOP %> diff --git a/app/views/get_a_teacher_relocation_payment/claims/_current_school_question.html.erb b/app/views/get_a_teacher_relocation_payment/claims/_current_school_question.html.erb new file mode 100644 index 0000000000..30b38736d9 --- /dev/null +++ b/app/views/get_a_teacher_relocation_payment/claims/_current_school_question.html.erb @@ -0,0 +1,3 @@ +

+ <%= label_tag :school_search, question, class: "govuk-label govuk-label--l" %> +

diff --git a/app/views/get_a_teacher_relocation_payment/claims/_current_school_search_results_question.html.erb b/app/views/get_a_teacher_relocation_payment/claims/_current_school_search_results_question.html.erb new file mode 100644 index 0000000000..a21b1c00ff --- /dev/null +++ b/app/views/get_a_teacher_relocation_payment/claims/_current_school_search_results_question.html.erb @@ -0,0 +1,5 @@ + +

+ <%= question %> +

+
diff --git a/app/views/get_a_teacher_relocation_payment/claims/employment_details.html.erb b/app/views/get_a_teacher_relocation_payment/claims/employment_details.html.erb deleted file mode 100644 index 069916b530..0000000000 --- a/app/views/get_a_teacher_relocation_payment/claims/employment_details.html.erb +++ /dev/null @@ -1,73 +0,0 @@ -<% content_for( - :page_title, - page_title( - t("get_a_teacher_relocation_payment.forms.employment_details.title"), - journey: current_journey_routing_name, - show_error: @form.errors.any? - ) -) %> -
-
-

- <%= t("get_a_teacher_relocation_payment.forms.employment_details.title") %> -

- - <%= form_for( - @form, - url: claim_path(current_journey_routing_name), - builder: GOVUKDesignSystemFormBuilder::FormBuilder - ) do |f| %> - <%= f.govuk_error_summary %> - - <%= f.govuk_text_field( - :school_headteacher_name, - label: { - text: t("get_a_teacher_relocation_payment.forms.employment_details.questions.school_headteacher_name"), - }, - ) %> - - <%= f.govuk_text_field( - :school_name, - label: { - text: t("get_a_teacher_relocation_payment.forms.employment_details.questions.school_name"), - }, - ) %> - - <%= f.govuk_fieldset( - legend: { - text: t("get_a_teacher_relocation_payment.forms.employment_details.school_address_legend"), - }, - ) do %> - <%= f.govuk_text_field( - :school_address_line_1, - label: { - text: t("get_a_teacher_relocation_payment.forms.employment_details.questions.school_address_line_1"), - }, - ) %> - - <%= f.govuk_text_field( - :school_address_line_2, - label: { - text: t("get_a_teacher_relocation_payment.forms.employment_details.questions.school_address_line_2"), - }, - ) %> - - <%= f.govuk_text_field( - :school_city, - label: { - text: t("get_a_teacher_relocation_payment.forms.employment_details.questions.school_city"), - }, - ) %> - - <%= f.govuk_text_field( - :school_postcode, - label: { - text: t("get_a_teacher_relocation_payment.forms.employment_details.questions.school_postcode"), - }, - ) %> - <% end %> - - <%= f.govuk_submit %> - <% end %> -
-
diff --git a/app/views/get_a_teacher_relocation_payment/claims/headteacher_details.html.erb b/app/views/get_a_teacher_relocation_payment/claims/headteacher_details.html.erb new file mode 100644 index 0000000000..0559a1ffd0 --- /dev/null +++ b/app/views/get_a_teacher_relocation_payment/claims/headteacher_details.html.erb @@ -0,0 +1,30 @@ +<% content_for( + :page_title, + page_title( + t("get_a_teacher_relocation_payment.forms.headteacher_details.questions.school_headteacher_name"), + 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| %> + <%= f.govuk_error_summary %> + + <%= f.govuk_text_field( + :school_headteacher_name, + label: { + text: t("get_a_teacher_relocation_payment.forms.headteacher_details.questions.school_headteacher_name"), + size: "l", + tag: "h1" + }, + ) %> + + <%= f.govuk_submit %> + <% end %> +
+
diff --git a/config/analytics.yml b/config/analytics.yml index 1584ca664f..c690b55c19 100644 --- a/config/analytics.yml +++ b/config/analytics.yml @@ -200,6 +200,7 @@ shared: - visa_type - date_of_entry - nationality + - current_school_id :schools: - id - urn diff --git a/config/analytics_blocklist.yml b/config/analytics_blocklist.yml index ba7e227dd4..14a3184c1c 100644 --- a/config/analytics_blocklist.yml +++ b/config/analytics_blocklist.yml @@ -99,11 +99,6 @@ :international_relocation_payments_eligibilities: - passport_number - school_headteacher_name - - school_name - - school_address_line_1 - - school_address_line_2 - - school_city - - school_postcode :levelling_up_premium_payments_eligibilities: - teacher_reference_number :early_career_payments_eligibilities: diff --git a/config/locales/en.yml b/config/locales/en.yml index 1c9fb284fc..58e74ef139 100644 --- a/config/locales/en.yml +++ b/config/locales/en.yml @@ -752,22 +752,15 @@ en: errors: presence: "Enter your passport number" invalid: "Invalid passport number" - employment_details: - title: "Employment information" - school_address_legend: "Enter the school address" + current_school: + questions: + current_school_search: "Which school are you currently employed to teach at?" + current_school_results: "Which school are you currently employed to teach at?" + headteacher_details: questions: school_headteacher_name: "Enter the name of the headteacher of the school where you are employed as a teacher" - school_name: "Enter the name of the school" - school_address_line_1: "Address line 1" - school_address_line_2: "Address line 2" - school_city: "Town or city" - school_postcode: "Postcode" errors: school_headteacher_name: "Enter the headteacher's name" - school_name: "Enter the school name" - school_address_line_1: "Enter your school's address" - school_city: "Enter your school's city" - school_postcode: "Enter a valid postcode (for example, BN1 1AA)" check_your_answers: part_one: diff --git a/db/migrate/20240627121651_drop_eligibility_columns_from_international_relocation_payments.rb b/db/migrate/20240627121651_drop_eligibility_columns_from_international_relocation_payments.rb new file mode 100644 index 0000000000..1363625ff2 --- /dev/null +++ b/db/migrate/20240627121651_drop_eligibility_columns_from_international_relocation_payments.rb @@ -0,0 +1,9 @@ +class DropEligibilityColumnsFromInternationalRelocationPayments < ActiveRecord::Migration[7.0] + def change + remove_column :international_relocation_payments_eligibilities, :school_name + remove_column :international_relocation_payments_eligibilities, :school_address_line_1 + remove_column :international_relocation_payments_eligibilities, :school_address_line_2 + remove_column :international_relocation_payments_eligibilities, :school_city + remove_column :international_relocation_payments_eligibilities, :school_postcode + end +end diff --git a/db/migrate/20240627145713_add_current_school_id_to_international_relocation_payments_eligibilities.rb b/db/migrate/20240627145713_add_current_school_id_to_international_relocation_payments_eligibilities.rb new file mode 100644 index 0000000000..e079c35faf --- /dev/null +++ b/db/migrate/20240627145713_add_current_school_id_to_international_relocation_payments_eligibilities.rb @@ -0,0 +1,11 @@ +class AddCurrentSchoolIdToInternationalRelocationPaymentsEligibilities < ActiveRecord::Migration[7.0] + def change + add_reference :international_relocation_payments_eligibilities, + :current_school, + type: :uuid, + foreign_key: {to_table: :schools}, + index: { + name: "index_irb_eligibilities_on_current_school_id" + } + end +end diff --git a/db/schema.rb b/db/schema.rb index f63cb06b77..ff00b13637 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_27_114644) do +ActiveRecord::Schema[7.0].define(version: 2024_06_27_145713) do # These are extensions that must be enabled in order to support this database enable_extension "pg_trgm" enable_extension "pgcrypto" @@ -200,11 +200,8 @@ t.string "nationality" t.string "passport_number" t.string "school_headteacher_name" - t.string "school_name" - t.string "school_address_line_1" - t.string "school_address_line_2" - t.string "school_city" - t.string "school_postcode" + t.uuid "current_school_id" + t.index ["current_school_id"], name: "index_irb_eligibilities_on_current_school_id" end create_table "journey_configurations", primary_key: "routing_name", id: :string, force: :cascade do |t| @@ -488,6 +485,7 @@ add_foreign_key "claims", "journeys_sessions" add_foreign_key "decisions", "dfe_sign_in_users", column: "created_by_id" add_foreign_key "early_career_payments_eligibilities", "schools", column: "current_school_id" + add_foreign_key "international_relocation_payments_eligibilities", "schools", column: "current_school_id" add_foreign_key "levelling_up_premium_payments_eligibilities", "schools", column: "current_school_id" add_foreign_key "notes", "claims" add_foreign_key "notes", "dfe_sign_in_users", column: "created_by_id" 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 fc70a880c8..95afde839f 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 @@ -67,12 +67,8 @@ end trait :with_employment_details do + current_school_id { create(:school).id } school_headteacher_name { "Seymour Skinner" } - school_name { "Springfield Elementary School" } - school_address_line_1 { "Springfield Elementary School" } - school_address_line_2 { "Plympton Street" } - school_city { "Springfield" } - school_postcode { "TE57 1NG" } end trait :eligible_teacher do 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 26fc3916a9..2e4183a112 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 @@ -15,6 +15,10 @@ contract_start_date - 1.week end + let(:school) do + create(:school) + end + before do journey_configuration end @@ -41,31 +45,33 @@ it "submits an application" do and_i_complete_the_nationality_step_with(option: "Australian") and_i_complete_the_passport_number_step_with(options: "123456789") - and_i_complete_the_employment_details_step + and_i_complete_the_current_school_step(school) + and_i_complete_the_headteacher_step and_i_complete_the_personal_details_step and_i_complete_the_postcode_step and_i_complete_the_email_address_step and_i_dont_provide_my_mobile_number and_i_provide_my_personal_bank_details and_i_complete_the_payroll_gender_step - then_the_check_your_answers_part_page_shows_my_answers + then_the_check_your_answers_part_page_shows_my_answers(school) and_i_submit_the_application then_the_application_is_submitted_successfully end end context "without postcode search" do - it "submits an application" do + it "submits an application", js: true do and_i_complete_the_nationality_step_with(option: "Australian") and_i_complete_the_passport_number_step_with(options: "123456789") - and_i_complete_the_employment_details_step + and_i_complete_the_current_school_step(school) + and_i_complete_the_headteacher_step and_i_complete_the_personal_details_step and_i_complete_the_manual_address_step and_i_complete_the_email_address_step and_i_dont_provide_my_mobile_number and_i_provide_my_personal_bank_details and_i_complete_the_payroll_gender_step - then_the_check_your_answers_part_page_shows_my_answers + then_the_check_your_answers_part_page_shows_my_answers(school) and_i_submit_the_application then_the_application_is_submitted_successfully end @@ -75,14 +81,15 @@ it "submits an application" do and_i_complete_the_nationality_step_with(option: "Australian") and_i_complete_the_passport_number_step_with(options: "123456789") - and_i_complete_the_employment_details_step + and_i_complete_the_current_school_step(school) + and_i_complete_the_headteacher_step and_i_complete_the_personal_details_step and_i_complete_the_manual_address_step and_i_complete_the_email_address_step and_i_provide_my_mobile_number and_i_provide_my_personal_bank_details and_i_complete_the_payroll_gender_step - then_the_check_your_answers_part_page_shows_my_answers(mobile_number: true) + then_the_check_your_answers_part_page_shows_my_answers(school, mobile_number: true) and_i_submit_the_application then_the_application_is_submitted_successfully end @@ -92,7 +99,8 @@ it "submits an application" do and_i_complete_the_nationality_step_with(option: "Australian") and_i_complete_the_passport_number_step_with(options: "123456789") - and_i_complete_the_employment_details_step + and_i_complete_the_current_school_step(school) + and_i_complete_the_headteacher_step and_i_complete_the_personal_details_step and_i_complete_the_manual_address_step and_i_complete_the_email_address_step @@ -100,6 +108,7 @@ and_i_provide_my_building_society_details and_i_complete_the_payroll_gender_step then_the_check_your_answers_part_page_shows_my_answers( + school, mobile_number: true, building_society: true ) @@ -141,7 +150,7 @@ def then_the_check_your_answers_part_one_page_shows_my_answers ) end - def then_the_check_your_answers_part_page_shows_my_answers(mobile_number: false, building_society: false) + def then_the_check_your_answers_part_page_shows_my_answers(school, mobile_number: false, building_society: false) expect(page).to have_text( "What is your full name? Walter Seymour Skinner" ) @@ -173,17 +182,9 @@ def then_the_check_your_answers_part_page_shows_my_answers(mobile_number: false, ) expect(page).to have_text( - "Enter the name of the school Springfield Elementary School" + "Which school are you currently employed to teach at? #{school.name}" ) - expect(page).to have_text("Address line 1 Springfield Elementary School") - - expect(page).to have_text("Address line 2 Plympton Street") - - expect(page).to have_text("Town or city Springfield") - - expect(page).to have_text("Postcode TE57 1NG") - if mobile_number expect(page).to have_text("Mobile number 01234567890") else diff --git a/spec/forms/journeys/get_a_teacher_relocation_payment/claim_submission_form_spec.rb b/spec/forms/journeys/get_a_teacher_relocation_payment/claim_submission_form_spec.rb index dbee398f69..f9bbba704f 100644 --- a/spec/forms/journeys/get_a_teacher_relocation_payment/claim_submission_form_spec.rb +++ b/spec/forms/journeys/get_a_teacher_relocation_payment/claim_submission_form_spec.rb @@ -49,11 +49,7 @@ nationality: "Australian", passport_number: "1234567890123456789A", school_headteacher_name: "Seymour Skinner", - school_name: "Springfield Elementary School", - school_address_line_1: "Springfield Elementary School", - school_address_line_2: "Plympton Street", - school_city: "Springfield", - school_postcode: "TE57 1NG" + current_school_id: create(:school).id } end diff --git a/spec/forms/journeys/get_a_teacher_relocation_payment/employment_details_form_spec.rb b/spec/forms/journeys/get_a_teacher_relocation_payment/employment_details_form_spec.rb deleted file mode 100644 index fd30f27460..0000000000 --- a/spec/forms/journeys/get_a_teacher_relocation_payment/employment_details_form_spec.rb +++ /dev/null @@ -1,101 +0,0 @@ -require "rails_helper" - -RSpec.describe Journeys::GetATeacherRelocationPayment::EmploymentDetailsForm, type: :model do - let(:journey_session) { create(:get_a_teacher_relocation_payment_session) } - - let(:params) { ActionController::Parameters.new(claim: {}) } - - let(:form) do - described_class.new( - journey_session: journey_session, - journey: Journeys::GetATeacherRelocationPayment, - params: params - ) - end - - describe "validations" do - subject { form } - - it do - is_expected.to( - validate_presence_of(:school_headteacher_name) - .with_message("Enter the headteacher's name") - ) - end - - it do - is_expected.to( - validate_presence_of(:school_name) - .with_message("Enter the school name") - ) - end - - it do - is_expected.to( - validate_presence_of(:school_address_line_1) - .with_message("Enter your school's address") - ) - end - - it do - is_expected.to( - validate_presence_of(:school_city) - .with_message("Enter your school's city") - ) - end - - it do - is_expected.not_to( - allow_value(nil) - .for(:school_postcode) - .with_message("Enter a valid postcode (for example, BN1 1AA)") - ) - end - - it do - is_expected.not_to( - allow_value("fff fff") - .for(:school_postcode) - .with_message("Enter a valid postcode (for example, BN1 1AA)") - ) - end - - it { is_expected.to(allow_value("BN1 1AA").for(:school_postcode)) } - end - - describe "#save" do - let(:params) do - ActionController::Parameters.new(claim: { - school_headteacher_name: "Seymour Skinner", - school_name: "Springfield Elementary School", - school_address_line_1: "19", - school_address_line_2: "Plympton Street", - school_city: "Springfield", - school_postcode: "TE57 1NG" - }) - end - - it "updates the journey session" do - expect { expect(form.save).to be(true) }.to( - change { journey_session.reload.answers.school_headteacher_name } - .to("Seymour Skinner") - .and( - change { journey_session.reload.answers.school_name } - .to("Springfield Elementary School") - ).and( - change { journey_session.reload.answers.school_address_line_1 } - .to("19") - ).and( - change { journey_session.reload.answers.school_address_line_2 } - .to("Plympton Street") - ).and( - change { journey_session.reload.answers.school_city } - .to("Springfield") - ).and( - change { journey_session.reload.answers.school_postcode } - .to("TE57 1NG") - ) - ) - end - end -end diff --git a/spec/forms/journeys/get_a_teacher_relocation_payment/headteacher_details_form_spec.rb b/spec/forms/journeys/get_a_teacher_relocation_payment/headteacher_details_form_spec.rb new file mode 100644 index 0000000000..faebf90e14 --- /dev/null +++ b/spec/forms/journeys/get_a_teacher_relocation_payment/headteacher_details_form_spec.rb @@ -0,0 +1,41 @@ +require "rails_helper" + +RSpec.describe Journeys::GetATeacherRelocationPayment::HeadteacherDetailsForm, type: :model do + let(:journey_session) { create(:get_a_teacher_relocation_payment_session) } + + let(:params) { ActionController::Parameters.new(claim: {}) } + + let(:form) do + described_class.new( + journey_session: journey_session, + journey: Journeys::GetATeacherRelocationPayment, + params: params + ) + end + + describe "validations" do + subject { form } + + it do + is_expected.to( + validate_presence_of(:school_headteacher_name) + .with_message("Enter the headteacher's name") + ) + end + end + + describe "#save" do + let(:params) do + ActionController::Parameters.new(claim: { + school_headteacher_name: "Seymour Skinner" + }) + end + + it "updates the journey session" do + expect { expect(form.save).to be(true) }.to( + change { journey_session.reload.answers.school_headteacher_name } + .to("Seymour Skinner") + ) + 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 54190e5b58..8023a9bb13 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 @@ -105,34 +105,14 @@ it do is_expected.to include( [ - "Enter the name of the headteacher of the school where you are employed as a teacher", - "Seymour Skinner", - "employment-details" - ], - [ - "Enter the name of the school", - "Springfield Elementary School", - "employment-details" - ], - [ - "Address line 1", - "Springfield Elementary School", - "employment-details" + "Which school are you currently employed to teach at?", + answers.current_school.name, + "current-school" ], [ - "Address line 2", - "Plympton Street", - "employment-details" - ], - [ - "Town or city", - "Springfield", - "employment-details" - ], - [ - "Postcode", - "TE57 1NG", - "employment-details" + "Enter the name of the headteacher of the school where you are employed as a teacher", + "Seymour Skinner", + "headteacher-details" ] ) 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 06c9234728..bf8369cd4a 100644 --- a/spec/support/get_a_teacher_relocation_payment/step_helpers.rb +++ b/spec/support/get_a_teacher_relocation_payment/step_helpers.rb @@ -93,26 +93,28 @@ def and_i_complete_the_passport_number_step_with(options:) click_button("Continue") end - def and_i_complete_the_employment_details_step - assert_on_employment_details_page! + def and_i_complete_the_current_school_step(school) + assert_on_current_school_page! fill_in( - "Enter the name of the headteacher of the school where you are employed as a teacher", - with: "Seymour Skinner" + "Which school are you currently employed to teach at?", + with: school.name ) - fill_in( - "Enter the name of the school", - with: "Springfield Elementary School" - ) + click_button "Continue" - fill_in("Address line 1", with: "Springfield Elementary School") + choose school.name - fill_in("Address line 2", with: "Plympton Street") + click_button "Continue" + end - fill_in("Town or city", with: "Springfield") + def and_i_complete_the_headteacher_step + assert_on_headteacher_page! - fill_in("Postcode", with: "TE57 1NG") + fill_in( + "Enter the name of the headteacher of the school where you are employed as a teacher", + with: "Seymour Skinner" + ) click_button("Continue") end @@ -315,8 +317,16 @@ def assert_on_passport_number_page! ) end - def assert_on_employment_details_page! - expect(page).to have_text("Employment information") + def assert_on_current_school_page! + expect(page).to have_text( + "Which school are you currently employed to teach at?" + ) + end + + def assert_on_headteacher_page! + expect(page).to have_text( + "Enter the name of the headteacher of the school where you are employed as a teacher" + ) end def assert_on_personal_details_page! From b2b5b4a45608f8351c7ab0ee7f85a56ac0e19082 Mon Sep 17 00:00:00 2001 From: Phil Lee Date: Fri, 28 Jun 2024 11:38:48 +0100 Subject: [PATCH 38/66] FE journey school search only returns FE bodies --- .../javascripts/components/college_search.js.erb | 4 +++- app/controllers/school_search_controller.rb | 3 ++- .../select_provision_form.rb | 4 ++-- app/models/school.rb | 10 ++++++++-- .../further_education_provision_search.html.erb | 1 + spec/factories/schools.rb | 4 ++++ .../happy_js_path_spec.rb | 2 +- .../happy_path_spec.rb | 2 +- spec/models/school_spec.rb | 8 +++++++- spec/requests/school_search_spec.rb | 16 ++++++++++++++++ 10 files changed, 45 insertions(+), 9 deletions(-) diff --git a/app/assets/javascripts/components/college_search.js.erb b/app/assets/javascripts/components/college_search.js.erb index 1bafbf668c..4c95cdd4bb 100644 --- a/app/assets/javascripts/components/college_search.js.erb +++ b/app/assets/javascripts/components/college_search.js.erb @@ -7,6 +7,8 @@ document.addEventListener("DOMContentLoaded", function () { return; } + var feOnly = form.dataset.feOnly || false; + var searchInputContainer = form.querySelector("#autocomplete-container"); if (!searchInputContainer) { @@ -57,7 +59,7 @@ document.addEventListener("DOMContentLoaded", function () { Rails.ajax({ type: "post", url: "<%= Rails.application.routes.url_helpers.school_search_index_path %>", - data: "query=" + query, + data: "query=" + query + "&fe_only=" + feOnly.toString(), success: handleResponse, error: handleResponse }); diff --git a/app/controllers/school_search_controller.rb b/app/controllers/school_search_controller.rb index 4a25d0b5cc..87f977f848 100644 --- a/app/controllers/school_search_controller.rb +++ b/app/controllers/school_search_controller.rb @@ -15,10 +15,11 @@ def search_schools return end + fe_only = ActiveModel::Type::Boolean.new.cast(params[:fe_only]) schools = ActiveModel::Type::Boolean.new.cast(params[:exclude_closed]) ? School.open : School begin - @schools = schools.search(params[:query]) + @schools = schools.search(params[:query], fe_only:) rescue ArgumentError => e raise unless e.message == School::SEARCH_NOT_ENOUGH_CHARACTERS_ERROR diff --git a/app/forms/journeys/further_education_payments/select_provision_form.rb b/app/forms/journeys/further_education_payments/select_provision_form.rb index 094d9a5562..76b7b7ae32 100644 --- a/app/forms/journeys/further_education_payments/select_provision_form.rb +++ b/app/forms/journeys/further_education_payments/select_provision_form.rb @@ -22,9 +22,9 @@ def save def results @results ||= if journey_session.answers.school_id.present? - School.open.where(id: school_id) + School.open.fe_only.where(id: school_id) else - School.open.search(provision_search) + School.open.fe_only.search(provision_search) end end diff --git a/app/models/school.rb b/app/models/school.rb index cd2ab667e5..a9f68f456e 100644 --- a/app/models/school.rb +++ b/app/models/school.rb @@ -15,6 +15,8 @@ class School < ApplicationRecord validates :school_type_group, presence: true validates :school_type, presence: true + scope :fe_only, -> { where(phase: 6) } # PhaseOfEducation == 16 plus + PHASES = { not_applicable: 0, nursery: 1, @@ -119,7 +121,7 @@ class School < ApplicationRecord before_save :sanitise_postcode_search_index - def self.search(search_term) + def self.search(search_term, fe_only: false) raise ArgumentError, SEARCH_NOT_ENOUGH_CHARACTERS_ERROR if search_term.length < SEARCH_MINIMUM_LENGTH search_field = :name @@ -131,10 +133,14 @@ def self.search(search_term) search_field, search_term = [:postcode_sanitised, sanitised_search_term] end - where("#{search_field} ILIKE ?", "%#{sanitize_sql_like(search_term)}%") + sql = where("#{search_field} ILIKE ?", "%#{sanitize_sql_like(search_term)}%") .order(sanitize_sql_for_order([Arel.sql("similarity(#{search_field}, ?) DESC"), search_term])) .order(:name, close_date: :desc) .limit(SEARCH_RESULTS_LIMIT) + + sql = sql.fe_only if fe_only + + sql end def address diff --git a/app/views/further_education_payments/claims/further_education_provision_search.html.erb b/app/views/further_education_payments/claims/further_education_provision_search.html.erb index cd277659f2..6e7291dcb1 100644 --- a/app/views/further_education_payments/claims/further_education_provision_search.html.erb +++ b/app/views/further_education_payments/claims/further_education_provision_search.html.erb @@ -5,6 +5,7 @@ method: :patch, builder: GOVUKDesignSystemFormBuilder::FormBuilder, id: "further-education-provision-search-form", + data: { "fe-only" => true }, html: { novalidate: false } do |f| %> <%= f.govuk_error_summary %> diff --git a/spec/factories/schools.rb b/spec/factories/schools.rb index 70cb2fe9cd..80aa124cc8 100644 --- a/spec/factories/schools.rb +++ b/spec/factories/schools.rb @@ -133,5 +133,9 @@ open_date { 10.days.ago } close_date { nil } end + + trait :further_education do + phase { 6 } + end end end diff --git a/spec/features/further_education_payments/happy_js_path_spec.rb b/spec/features/further_education_payments/happy_js_path_spec.rb index f3eb04fc25..728b02af49 100644 --- a/spec/features/further_education_payments/happy_js_path_spec.rb +++ b/spec/features/further_education_payments/happy_js_path_spec.rb @@ -1,7 +1,7 @@ require "rails_helper" RSpec.feature "Further education payments", js: true, flaky: true do - let(:college) { create(:school) } + let(:college) { create(:school, :further_education) } scenario "happy js path" do when_further_education_payments_journey_configuration_exists diff --git a/spec/features/further_education_payments/happy_path_spec.rb b/spec/features/further_education_payments/happy_path_spec.rb index 03bd448a56..f6213fa09f 100644 --- a/spec/features/further_education_payments/happy_path_spec.rb +++ b/spec/features/further_education_payments/happy_path_spec.rb @@ -1,7 +1,7 @@ require "rails_helper" RSpec.feature "Further education payments" do - let(:college) { create(:school) } + let(:college) { create(:school, :further_education) } scenario "happy path claim" do when_further_education_payments_journey_configuration_exists diff --git a/spec/models/school_spec.rb b/spec/models/school_spec.rb index 2c44c5abe9..35fcccabd8 100644 --- a/spec/models/school_spec.rb +++ b/spec/models/school_spec.rb @@ -12,7 +12,7 @@ describe ".search" do let!(:first_school) { create(:school, name: "Community School London", postcode: "SW1P 3BT") } let!(:second_school) { create(:school, name: "Unity School London", postcode: "SW1P 3BT") } - let!(:third_school) { create(:school, name: "The Unity College Manchester", postcode: "M1 2WD") } + let!(:third_school) { create(:school, :further_education, name: "The Unity College Manchester", postcode: "M1 2WD") } it "returns schools with a name matching the search term" do expect(School.search("School")).to match_array([first_school, second_school]) @@ -38,6 +38,12 @@ it "orders the results by similarity" do expect(School.search("Unity School")).to eq([second_school, first_school]) end + + context "when searching for FE only" do + it "only returns FE bodies" do + expect(School.search("Unity", fe_only: true)).to eq([third_school]) + end + end end describe "#address" do diff --git a/spec/requests/school_search_spec.rb b/spec/requests/school_search_spec.rb index 3e9494835a..7b3ed2d28b 100644 --- a/spec/requests/school_search_spec.rb +++ b/spec/requests/school_search_spec.rb @@ -75,5 +75,21 @@ expect(response.body).to include(other_school_similar_name.name) end end + + context "when searching for FE only" do + let!(:school_3) { create(:school, :further_education, name: "some college") } + + before do + school_1.update(name: "some school") + school_2.update(name: "some school") + end + + it "only returns FE bodies" do + post school_search_index_path, params: {query: "some", fe_only: true} + + expect(JSON.parse(response.body)["data"].size).to eql(1) + expect(response.body).to include("some college") + end + end end end From fb28f8e709d401cbf3c154b8e918eb4e63b0cd17 Mon Sep 17 00:00:00 2001 From: Phil Lee Date: Fri, 28 Jun 2024 15:06:55 +0100 Subject: [PATCH 39/66] link to FE eligible providers --- .../claims/further_education_provision_search.html.erb | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/app/views/further_education_payments/claims/further_education_provision_search.html.erb b/app/views/further_education_payments/claims/further_education_provision_search.html.erb index 6e7291dcb1..3e9061c8e7 100644 --- a/app/views/further_education_payments/claims/further_education_provision_search.html.erb +++ b/app/views/further_education_payments/claims/further_education_provision_search.html.erb @@ -26,7 +26,7 @@ type: :bullet %>

- If you are unsure if your FE provider is eligible, you can refer to the full list of eligible FE providers for more information. + If you are unsure if your FE provider is eligible, you can refer to the <%= govuk_link_to "full list of eligible FE providers", "https://assets.publishing.service.gov.uk/media/667300fe64e554df3bd0db92/List_of_eligible_FE_providers_and_payment_value_for_levelling_up_premium.xlsx" %> for more information.

From a5cc1482de40d7c0bef50bf8d6c7901683c9d248 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Fri, 28 Jun 2024 16:50:59 +0100 Subject: [PATCH 40/66] Bump rails_semantic_logger from 4.14.0 to 4.15.0 (#2944) Bumps [rails_semantic_logger](https://github.com/reidmorrison/rails_semantic_logger) from 4.14.0 to 4.15.0. - [Commits](https://github.com/reidmorrison/rails_semantic_logger/compare/v4.14.0...v4.15.0) --- updated-dependencies: - dependency-name: rails_semantic_logger dependency-type: direct:production update-type: version-update:semver-minor ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- Gemfile.lock | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Gemfile.lock b/Gemfile.lock index c4166d55c0..90bde271b3 100644 --- a/Gemfile.lock +++ b/Gemfile.lock @@ -374,7 +374,7 @@ GEM rails-html-sanitizer (1.6.0) loofah (~> 2.21) nokogiri (~> 1.14) - rails_semantic_logger (4.14.0) + rails_semantic_logger (4.15.0) rack railties (>= 5.1) semantic_logger (~> 4.13) From fbb76899f171d8bf3465e0746beb43ca61661215 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Fri, 28 Jun 2024 17:17:20 +0100 Subject: [PATCH 41/66] Bump pagy from 8.5.0 to 8.6.1 (#2945) Bumps [pagy](https://github.com/ddnexus/pagy) from 8.5.0 to 8.6.1. - [Release notes](https://github.com/ddnexus/pagy/releases) - [Changelog](https://github.com/ddnexus/pagy/blob/master/CHANGELOG.md) - [Commits](https://github.com/ddnexus/pagy/compare/8.5.0...8.6.1) --- updated-dependencies: - dependency-name: pagy dependency-type: direct:production update-type: version-update:semver-minor ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- Gemfile.lock | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Gemfile.lock b/Gemfile.lock index 90bde271b3..a113c9b12d 100644 --- a/Gemfile.lock +++ b/Gemfile.lock @@ -320,7 +320,7 @@ GEM validate_url webfinger (~> 1.2) os (1.1.4) - pagy (8.5.0) + pagy (8.6.1) parallel (1.25.1) parallel_tests (4.7.1) parallel From 2139aecc25c6663ac90b99887c0e463f019b26c6 Mon Sep 17 00:00:00 2001 From: Phil Lee Date: Tue, 25 Jun 2024 16:31:11 +0100 Subject: [PATCH 42/66] add FE contract type --- .../contract_type_form.rb | 36 ++++++++++++++ .../journeys/further_education_payments.rb | 1 + .../session_answers.rb | 5 ++ .../claims/contract_type.html.erb | 13 +++-- config/locales/en.yml | 4 ++ .../session_answers.rb | 4 ++ .../happy_js_path_spec.rb | 3 +- .../happy_path_spec.rb | 3 +- .../contract_type_form_spec.rb | 48 +++++++++++++++++++ 9 files changed, 111 insertions(+), 6 deletions(-) create mode 100644 app/forms/journeys/further_education_payments/contract_type_form.rb create mode 100644 spec/factories/journeys/further_education_payments/session_answers.rb create mode 100644 spec/forms/journeys/further_education_payments/contract_type_form_spec.rb diff --git a/app/forms/journeys/further_education_payments/contract_type_form.rb b/app/forms/journeys/further_education_payments/contract_type_form.rb new file mode 100644 index 0000000000..ab2f408ced --- /dev/null +++ b/app/forms/journeys/further_education_payments/contract_type_form.rb @@ -0,0 +1,36 @@ +module Journeys + module FurtherEducationPayments + class ContractTypeForm < Form + attribute :contract_type, :string + + validates :contract_type, + inclusion: {in: ->(form) { form.radio_options.map(&:id) }, message: i18n_error_message(:inclusion)} + + def radio_options + [ + OpenStruct.new( + id: "permanent", + name: "Permanent contract", + hint: "This includes full-time and part-time contracts" + ), + OpenStruct.new( + id: "fixed-term", + name: "Fixed-term contract" + ), + OpenStruct.new( + id: "variable-hours", + name: "Variable hours contract", + hint: "This includes zero hours contract and hourly paid" + ) + ] + end + + def save + return if invalid? + + journey_session.answers.assign_attributes(contract_type:) + journey_session.save! + end + end + end +end diff --git a/app/models/journeys/further_education_payments.rb b/app/models/journeys/further_education_payments.rb index 831bde3558..1ff183dfe7 100644 --- a/app/models/journeys/further_education_payments.rb +++ b/app/models/journeys/further_education_payments.rb @@ -12,6 +12,7 @@ module FurtherEducationPayments "teaching-responsibilities" => TeachingResponsibilitiesForm, "further-education-provision-search" => FurtherEducationProvisionSearchForm, "select-provision" => SelectProvisionForm, + "contract-type" => ContractTypeForm, "subjects-taught" => SubjectsTaughtForm } } diff --git a/app/models/journeys/further_education_payments/session_answers.rb b/app/models/journeys/further_education_payments/session_answers.rb index 07cedd8d3d..4210d73a3b 100644 --- a/app/models/journeys/further_education_payments/session_answers.rb +++ b/app/models/journeys/further_education_payments/session_answers.rb @@ -4,7 +4,12 @@ class SessionAnswers < Journeys::SessionAnswers attribute :teaching_responsibilities, :boolean attribute :provision_search, :string attribute :school_id, :string # GUID + attribute :contract_type, :string attribute :subjects_taught, default: [] + + def school + @school ||= School.find(school_id) + end end end end diff --git a/app/views/further_education_payments/claims/contract_type.html.erb b/app/views/further_education_payments/claims/contract_type.html.erb index ca9afd0738..6da1881189 100644 --- a/app/views/further_education_payments/claims/contract_type.html.erb +++ b/app/views/further_education_payments/claims/contract_type.html.erb @@ -1,7 +1,12 @@ -

- FE contract type goes here -

- <%= form_with model: @form, url: claim_path(current_journey_routing_name), method: :patch, builder: GOVUKDesignSystemFormBuilder::FormBuilder, html: { novalidate: false } do |f| %> + <%= f.govuk_error_summary %> + + <%= f.govuk_collection_radio_buttons :contract_type, @form.radio_options, :id, :name, :hint, + legend: { + text: @form.t(:question, school_name: journey_session.answers.school.name), + tag: "h1", + size: "l" + } %> + <%= f.govuk_submit %> <% end %> diff --git a/config/locales/en.yml b/config/locales/en.yml index 58e74ef139..63e910cfb4 100644 --- a/config/locales/en.yml +++ b/config/locales/en.yml @@ -788,6 +788,10 @@ en: select_provision: errors: blank: Select the college you teach at + contract_type: + question: What type of contract do you have with %{school_name}? + errors: + inclusion: Select the contract type you have subjects_taught: question: Which subject areas do you teach? hint: Select all that apply diff --git a/spec/factories/journeys/further_education_payments/session_answers.rb b/spec/factories/journeys/further_education_payments/session_answers.rb new file mode 100644 index 0000000000..9c2bf044aa --- /dev/null +++ b/spec/factories/journeys/further_education_payments/session_answers.rb @@ -0,0 +1,4 @@ +FactoryBot.define do + factory :further_education_payments_answers, class: "Journeys::FurtherEducationPayments::SessionAnswers" do + end +end diff --git a/spec/features/further_education_payments/happy_js_path_spec.rb b/spec/features/further_education_payments/happy_js_path_spec.rb index 728b02af49..11c728af8d 100644 --- a/spec/features/further_education_payments/happy_js_path_spec.rb +++ b/spec/features/further_education_payments/happy_js_path_spec.rb @@ -26,7 +26,8 @@ expect(page).to have_selector "input[type=radio][checked=checked][value='#{college.id}']", visible: false click_button "Continue" - expect(page).to have_content("FE contract type goes here") + expect(page).to have_content("What type of contract do you have with #{college.name}?") + choose("Permanent contract") click_button "Continue" expect(page).to have_content("FE teaching hours per week goes here") diff --git a/spec/features/further_education_payments/happy_path_spec.rb b/spec/features/further_education_payments/happy_path_spec.rb index f6213fa09f..7e38c5c95b 100644 --- a/spec/features/further_education_payments/happy_path_spec.rb +++ b/spec/features/further_education_payments/happy_path_spec.rb @@ -23,7 +23,8 @@ choose college.name click_button "Continue" - expect(page).to have_content("FE contract type goes here") + expect(page).to have_content("What type of contract do you have with #{college.name}?") + choose("Permanent contract") click_button "Continue" expect(page).to have_content("FE teaching hours per week goes here") diff --git a/spec/forms/journeys/further_education_payments/contract_type_form_spec.rb b/spec/forms/journeys/further_education_payments/contract_type_form_spec.rb new file mode 100644 index 0000000000..47eb4cb6ea --- /dev/null +++ b/spec/forms/journeys/further_education_payments/contract_type_form_spec.rb @@ -0,0 +1,48 @@ +require "rails_helper" + +RSpec.describe Journeys::FurtherEducationPayments::ContractTypeForm, type: :model do + let(:journey) { Journeys::FurtherEducationPayments } + let(:journey_session) { create(:further_education_payments_session, answers:) } + let(:answers) { build(:further_education_payments_answers, school_id: college.id) } + let(:college) { create(:school) } + let(:contract_type) { nil } + + let(:params) do + ActionController::Parameters.new( + claim: { + contract_type: + } + ) + end + + subject do + described_class.new( + journey_session:, + journey:, + params: + ) + end + + describe "validations" do + context "when no option selected" do + it do + is_expected.not_to( + allow_value(nil) + .for(:contract_type) + .with_message("Select the contract type you have") + ) + end + end + end + + describe "#save" do + let(:contract_type) { %w[permanent fixed-term variable-hours].sample } + + it "updates the journey session" do + expect { expect(subject.save).to be(true) }.to( + change { journey_session.reload.answers.contract_type } + .to(contract_type) + ) + end + end +end From c6df4e4eadb6883714909400c84ea91b4e78f95c Mon Sep 17 00:00:00 2001 From: Richard Lynch Date: Fri, 28 Jun 2024 10:33:59 +0100 Subject: [PATCH 43/66] Add eligibility check for contract start date We want to reject claimants if their contract start date is earlier than 6 months before the autumn term. This commit updates the eligibility checker to do so and also adds some missing tests. --- app/models/academic_year.rb | 14 +- .../eligibility.rb | 14 +- .../policy_eligibility_checker.rb | 12 ++ ...eligible_route_completing_the_form_spec.rb | 14 +- .../teacher_route_completing_the_form_spec.rb | 3 +- spec/models/academic_year_spec.rb | 6 + .../policy_eligibility_checker_spec.rb | 139 +++++++++++++++++- 7 files changed, 179 insertions(+), 23 deletions(-) diff --git a/app/models/academic_year.rb b/app/models/academic_year.rb index 069a282531..a0588564e7 100644 --- a/app/models/academic_year.rb +++ b/app/models/academic_year.rb @@ -15,6 +15,9 @@ class AcademicYear ACADEMIC_YEAR_REGEXP = /\A20\d{2}\/20\d{2}\z/ + AUTUMN_TERM_START_MONTH = 9 + AUTUMN_TERM_START_DAY = 1 + attr_reader :start_year, :end_year # Defines a custom ActiveRecord::Type for AcademicYear that means we can @@ -52,7 +55,12 @@ def next def for(date) return if date.nil? - start_of_autumn_term = Date.new(date.year, 9, 1) + start_of_autumn_term = Date.new( + date.year, + AUTUMN_TERM_START_MONTH, + AUTUMN_TERM_START_DAY + ) + if date < start_of_autumn_term new(date.year - 1) else @@ -132,4 +140,8 @@ def -(other) def +(other) AcademicYear.new(start_year + other) end + + def start_of_autumn_term + Date.new(start_year, AUTUMN_TERM_START_MONTH, AUTUMN_TERM_START_DAY) + end end diff --git a/app/models/policies/international_relocation_payments/eligibility.rb b/app/models/policies/international_relocation_payments/eligibility.rb index 932d3c009f..abe3ad997c 100644 --- a/app/models/policies/international_relocation_payments/eligibility.rb +++ b/app/models/policies/international_relocation_payments/eligibility.rb @@ -3,6 +3,15 @@ module InternationalRelocationPayments class Eligibility < ApplicationRecord self.table_name = "international_relocation_payments_eligibilities" + PRE_ACADEMIC_YEAR_WINDOW_LIMIT = 6.months + + def self.earliest_eligible_contract_start_date + Journeys::GetATeacherRelocationPayment + .configuration + .current_academic_year + .start_of_autumn_term - PRE_ACADEMIC_YEAR_WINDOW_LIMIT + end + has_one :claim, as: :eligibility, inverse_of: :eligibility def ineligible? @@ -12,11 +21,6 @@ def ineligible? def policy Policies::InternationalRelocationPayments end - - def self.earliest_eligible_contract_start_date - # FIXME RL - waiting on policy to get back to us for what this should - # be - end end end end 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 300a3eda53..405f63f98d 100644 --- a/app/models/policies/international_relocation_payments/policy_eligibility_checker.rb +++ b/app/models/policies/international_relocation_payments/policy_eligibility_checker.rb @@ -35,6 +35,8 @@ def ineligible_reason "taught subject not accepted" in visa_type: "Other" "visa not accepted" + in start_date: Date unless contract_start_date_eligible? + "contract start date must be after #{earliest_eligible_contract_start_date}" 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 @@ -42,6 +44,16 @@ def ineligible_reason end end + def contract_start_date_eligible? + return false unless answers.start_date + + answers.start_date >= earliest_eligible_contract_start_date + end + + def earliest_eligible_contract_start_date + Eligibility.earliest_eligible_contract_start_date + end + def date_of_entry_eligible? return false unless answers.date_of_entry && answers.start_date 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 7f3c9d0235..dcf61efe83 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 @@ -8,11 +8,8 @@ end let(:contract_start_date) do - Date.new( - journey_configuration.current_academic_year.start_year, - 1, - 1 - ) + Policies::InternationalRelocationPayments::Eligibility + .earliest_eligible_contract_start_date end before do @@ -63,9 +60,7 @@ end end - # FIXME RL waiting on feedback from policy team to determine what the cut - # off date is for contracts - xcontext "ineligible - contract start date" do + context "ineligible - contract start date" do it "shows the ineligible page" do when_i_start_the_form and_i_complete_application_route_question_with( @@ -74,7 +69,8 @@ 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: Polices::InternationalRelocationPayments.earliest_eligible_contract_start_date - 1.day + date: Policies::InternationalRelocationPayments::Eligibility + .earliest_eligible_contract_start_date - 1.day ) then_i_see_the_ineligible_page end 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 2e4183a112..67c610239e 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 @@ -8,7 +8,8 @@ end let(:contract_start_date) do - Date.yesterday + Policies::InternationalRelocationPayments::Eligibility + .earliest_eligible_contract_start_date end let(:entry_date) do diff --git a/spec/models/academic_year_spec.rb b/spec/models/academic_year_spec.rb index 4724d09909..7a2f0f2816 100644 --- a/spec/models/academic_year_spec.rb +++ b/spec/models/academic_year_spec.rb @@ -186,4 +186,10 @@ expect(AcademicYear.new(2014).hash).not_to eql 2014.hash end end + + describe "#start_of_autumn_term" do + it "returns September 1st of the start year" do + expect(AcademicYear.new(2014).start_of_autumn_term).to eq Date.new(2014, 9, 1) + end + end end diff --git a/spec/models/policies/international_relocation_payments/policy_eligibility_checker_spec.rb b/spec/models/policies/international_relocation_payments/policy_eligibility_checker_spec.rb index 0a07362e28..758253ff2e 100644 --- a/spec/models/policies/international_relocation_payments/policy_eligibility_checker_spec.rb +++ b/spec/models/policies/international_relocation_payments/policy_eligibility_checker_spec.rb @@ -1,10 +1,14 @@ require "rails_helper" describe Policies::InternationalRelocationPayments::PolicyEligibilityChecker do + before do + create(:journey_configuration, :get_a_teacher_relocation_payment) + end + let(:answers) do build( :get_a_teacher_relocation_payment_answers, - application_route: application_route + attributes: attributes ) end @@ -14,19 +18,31 @@ subject { checker.status } context "when the application route is 'other'" do - let(:application_route) { "other" } + let(:attributes) do + { + application_route: "other" + } + end it { is_expected.to eq(:ineligible) } end context "when the application route is 'teacher'" do - let(:application_route) { "teacher" } + let(:attributes) do + { + application_route: "teacher" + } + end it { is_expected.to eq(:eligible_now) } end context "when the application route is 'salaried_trainee'" do - let(:application_route) { "salaried_trainee" } + let(:attributes) do + { + application_route: "salaried_trainee" + } + end it { is_expected.to eq(:ineligible) } end @@ -36,21 +52,130 @@ subject { checker.ineligible? } context "when the application route is 'other'" do - let(:application_route) { "other" } + let(:attributes) do + { + application_route: "other" + } + end it { is_expected.to eq(true) } end context "when the application route is 'teacher'" do - let(:application_route) { "teacher" } + let(:attributes) do + { + application_route: "teacher" + } + end it { is_expected.to eq(false) } end context "when the application route is 'salaried_trainee'" do - let(:application_route) { "salaried_trainee" } + let(:attributes) do + { + application_route: "salaried_trainee" + } + end + + it { is_expected.to eq(true) } + end + + context "with a non state funded secondary school" do + let(:attributes) do + { + application_route: "teacher", + state_funded_secondary_school: false + } + end + + it { is_expected.to eq(true) } + end + + context "with a contract duration of less than one year" do + let(:attributes) do + { + application_route: "teacher", + state_funded_secondary_school: true, + one_year: false + } + end + + it { is_expected.to eq(true) } + end + + context "with a taught subject of 'other'" do + let(:attributes) do + { + application_route: "teacher", + state_funded_secondary_school: true, + one_year: true, + subject: "other" + } + end + + it { is_expected.to eq(true) } + end + + context "with a visa type of 'Other'" do + let(:attributes) do + { + application_route: "teacher", + state_funded_secondary_school: true, + one_year: true, + subject: "physics", + visa_type: "Other" + } + end + + it { is_expected.to eq(true) } + end + + context "with a contract start date before the earliest eligible date" do + let(:attributes) do + { + application_route: "teacher", + state_funded_secondary_school: true, + one_year: true, + subject: "physics", + visa_type: "British National (Overseas) visa", + start_date: Policies::InternationalRelocationPayments::Eligibility.earliest_eligible_contract_start_date - 1.day + } + end it { is_expected.to eq(true) } end + + context "with an entry date more than 3 months before the contract start date" do + let(:attributes) do + { + application_route: "teacher", + state_funded_secondary_school: true, + one_year: true, + subject: "physics", + visa_type: "British National (Overseas) visa", + start_date: Policies::InternationalRelocationPayments::Eligibility.earliest_eligible_contract_start_date, + date_of_entry: Policies::InternationalRelocationPayments::Eligibility.earliest_eligible_contract_start_date - 4.months + } + end + + it { is_expected.to eq(true) } + end + + context "with an eligible application" do + let(:attributes) do + { + application_route: "teacher", + state_funded_secondary_school: true, + one_year: true, + subject: "physics", + visa_type: "British National (Overseas) visa", + start_date: Policies::InternationalRelocationPayments::Eligibility.earliest_eligible_contract_start_date, + date_of_entry: Policies::InternationalRelocationPayments::Eligibility.earliest_eligible_contract_start_date - 1.week + } + end + + it { is_expected.to eq(false) } + end end end From bceb2da17231faf5ad16f64b6c37ed4a8aa44cf3 Mon Sep 17 00:00:00 2001 From: Richard Lynch Date: Mon, 1 Jul 2024 10:17:52 +0100 Subject: [PATCH 44/66] Move date to policy checker We eventually want to get rid of the policy models, storing their data on the claim itself, so the policy eligibility checker is a better home for this method. --- .../eligibility.rb | 9 --------- .../policy_eligibility_checker.rb | 15 +++++++++++---- .../ineligible_route_completing_the_form_spec.rb | 4 ++-- .../teacher_route_completing_the_form_spec.rb | 2 +- .../policy_eligibility_checker_spec.rb | 10 +++++----- 5 files changed, 19 insertions(+), 21 deletions(-) diff --git a/app/models/policies/international_relocation_payments/eligibility.rb b/app/models/policies/international_relocation_payments/eligibility.rb index abe3ad997c..c5f1b73414 100644 --- a/app/models/policies/international_relocation_payments/eligibility.rb +++ b/app/models/policies/international_relocation_payments/eligibility.rb @@ -3,15 +3,6 @@ module InternationalRelocationPayments class Eligibility < ApplicationRecord self.table_name = "international_relocation_payments_eligibilities" - PRE_ACADEMIC_YEAR_WINDOW_LIMIT = 6.months - - def self.earliest_eligible_contract_start_date - Journeys::GetATeacherRelocationPayment - .configuration - .current_academic_year - .start_of_autumn_term - PRE_ACADEMIC_YEAR_WINDOW_LIMIT - end - has_one :claim, as: :eligibility, inverse_of: :eligibility def ineligible? 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 405f63f98d..67bbb0e329 100644 --- a/app/models/policies/international_relocation_payments/policy_eligibility_checker.rb +++ b/app/models/policies/international_relocation_payments/policy_eligibility_checker.rb @@ -1,10 +1,21 @@ module Policies module InternationalRelocationPayments class PolicyEligibilityChecker + PRE_ACADEMIC_YEAR_WINDOW_LIMIT = 6.months + + def self.earliest_eligible_contract_start_date + Journeys::GetATeacherRelocationPayment + .configuration + .current_academic_year + .start_of_autumn_term - PRE_ACADEMIC_YEAR_WINDOW_LIMIT + end + attr_reader :answers delegate_missing_to :answers + delegate :earliest_eligible_contract_start_date, to: :class + def initialize(answers:) @answers = answers end @@ -50,10 +61,6 @@ def contract_start_date_eligible? answers.start_date >= earliest_eligible_contract_start_date end - def earliest_eligible_contract_start_date - Eligibility.earliest_eligible_contract_start_date - end - def date_of_entry_eligible? return false unless answers.date_of_entry && answers.start_date 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 dcf61efe83..142384cbb3 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 @@ -8,7 +8,7 @@ end let(:contract_start_date) do - Policies::InternationalRelocationPayments::Eligibility + Policies::InternationalRelocationPayments::PolicyEligibilityChecker .earliest_eligible_contract_start_date end @@ -69,7 +69,7 @@ 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: Policies::InternationalRelocationPayments::Eligibility + date: Policies::InternationalRelocationPayments::PolicyEligibilityChecker .earliest_eligible_contract_start_date - 1.day ) 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 67c610239e..c9b9f22010 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 @@ -8,7 +8,7 @@ end let(:contract_start_date) do - Policies::InternationalRelocationPayments::Eligibility + Policies::InternationalRelocationPayments::PolicyEligibilityChecker .earliest_eligible_contract_start_date end diff --git a/spec/models/policies/international_relocation_payments/policy_eligibility_checker_spec.rb b/spec/models/policies/international_relocation_payments/policy_eligibility_checker_spec.rb index 758253ff2e..f43222143b 100644 --- a/spec/models/policies/international_relocation_payments/policy_eligibility_checker_spec.rb +++ b/spec/models/policies/international_relocation_payments/policy_eligibility_checker_spec.rb @@ -139,7 +139,7 @@ one_year: true, subject: "physics", visa_type: "British National (Overseas) visa", - start_date: Policies::InternationalRelocationPayments::Eligibility.earliest_eligible_contract_start_date - 1.day + start_date: Policies::InternationalRelocationPayments::PolicyEligibilityChecker.earliest_eligible_contract_start_date - 1.day } end @@ -154,8 +154,8 @@ one_year: true, subject: "physics", visa_type: "British National (Overseas) visa", - start_date: Policies::InternationalRelocationPayments::Eligibility.earliest_eligible_contract_start_date, - date_of_entry: Policies::InternationalRelocationPayments::Eligibility.earliest_eligible_contract_start_date - 4.months + start_date: Policies::InternationalRelocationPayments::PolicyEligibilityChecker.earliest_eligible_contract_start_date, + date_of_entry: Policies::InternationalRelocationPayments::PolicyEligibilityChecker.earliest_eligible_contract_start_date - 4.months } end @@ -170,8 +170,8 @@ one_year: true, subject: "physics", visa_type: "British National (Overseas) visa", - start_date: Policies::InternationalRelocationPayments::Eligibility.earliest_eligible_contract_start_date, - date_of_entry: Policies::InternationalRelocationPayments::Eligibility.earliest_eligible_contract_start_date - 1.week + start_date: Policies::InternationalRelocationPayments::PolicyEligibilityChecker.earliest_eligible_contract_start_date, + date_of_entry: Policies::InternationalRelocationPayments::PolicyEligibilityChecker.earliest_eligible_contract_start_date - 1.week } end From d7c78a7e1b0f3157fdd076e84d7e99ff3c8f4a9d Mon Sep 17 00:00:00 2001 From: Colin Saliceti Date: Thu, 27 Jun 2024 18:28:42 +0100 Subject: [PATCH 45/66] DNS domains infrastructure Create basic resources to manage domains: resource group, storage account, DNS zone and front door --- .gitignore | 1 + Makefile | 28 +++++++++++++++++++ global_config/domains.sh | 4 +++ .../infrastructure/config/zones.tfvars.json | 11 ++++++++ .../infrastructure/config/zones_Terrafile | 3 ++ terraform/domains/infrastructure/main.tf | 5 ++++ terraform/domains/infrastructure/terraform.tf | 19 +++++++++++++ terraform/domains/infrastructure/variables.tf | 7 +++++ 8 files changed, 78 insertions(+) create mode 100644 global_config/domains.sh create mode 100644 terraform/domains/infrastructure/config/zones.tfvars.json create mode 100644 terraform/domains/infrastructure/config/zones_Terrafile create mode 100644 terraform/domains/infrastructure/main.tf create mode 100644 terraform/domains/infrastructure/terraform.tf create mode 100644 terraform/domains/infrastructure/variables.tf diff --git a/.gitignore b/.gitignore index 350d286840..2609eac100 100644 --- a/.gitignore +++ b/.gitignore @@ -59,6 +59,7 @@ public/assets # AKS deployment .terraform terraform/application/vendor +terraform/domains/infrastructure/vendor terraform/domains/environment_domains/vendor terraform.tfstate* bin/terrafile diff --git a/Makefile b/Makefile index dc728c7dfa..8424f5b8f6 100644 --- a/Makefile +++ b/Makefile @@ -138,3 +138,31 @@ get-cluster-credentials: set-azure-account-aks bin/konduit.sh: curl -s https://raw.githubusercontent.com/DFE-Digital/teacher-services-cloud/main/scripts/konduit.sh -o bin/konduit.sh \ && chmod +x bin/konduit.sh + +domains-infra-init: bin/terrafile domains composed-variables set-azure-account-aks + ./bin/terrafile -p terraform/domains/infrastructure/vendor/modules -f terraform/domains/infrastructure/config/zones_Terrafile + + terraform -chdir=terraform/domains/infrastructure init -reconfigure -upgrade \ + -backend-config=resource_group_name=${RESOURCE_GROUP_NAME} \ + -backend-config=storage_account_name=${STORAGE_ACCOUNT_NAME} \ + -backend-config=key=domains_infrastructure.tfstate + +domains-infra-plan: domains domains-infra-init ## Terraform plan for DNS infrastructure (DNS zone and front door). Usage: make domains-infra-plan + terraform -chdir=terraform/domains/infrastructure plan -var-file config/zones.tfvars.json + +domains-infra-apply: domains domains-infra-init ## Terraform apply for DNS infrastructure (DNS zone and front door). Usage: make domains-infra-apply + terraform -chdir=terraform/domains/infrastructure apply -var-file config/zones.tfvars.json ${AUTO_APPROVE} + +domains-init: bin/terrafile domains composed-variables set-azure-account-aks + ./bin/terrafile -p terraform/domains/environment_domains/vendor/modules -f terraform/domains/environment_domains/config/${CONFIG}_Terrafile + + terraform -chdir=terraform/domains/environment_domains init -upgrade -reconfigure \ + -backend-config=resource_group_name=${RESOURCE_GROUP_NAME} \ + -backend-config=storage_account_name=${STORAGE_ACCOUNT_NAME} \ + -backend-config=key=${ENVIRONMENT}.tfstate + +domains-plan: domains-init ## Terraform plan for DNS environment domains. Usage: make development domains-plan + terraform -chdir=terraform/domains/environment_domains plan -var-file config/${CONFIG}.tfvars.json + +domains-apply: domains-init ## Terraform apply for DNS environment domains. Usage: make development domains-apply + terraform -chdir=terraform/domains/environment_domains apply -var-file config/${CONFIG}.tfvars.json ${AUTO_APPROVE} diff --git a/global_config/domains.sh b/global_config/domains.sh new file mode 100644 index 0000000000..a7b7641875 --- /dev/null +++ b/global_config/domains.sh @@ -0,0 +1,4 @@ +AZURE_SUBSCRIPTION=s189-teacher-services-cloud-production +AZURE_RESOURCE_PREFIX=s189p01 +CONFIG_SHORT=dom +DISABLE_KEYVAULTS=true diff --git a/terraform/domains/infrastructure/config/zones.tfvars.json b/terraform/domains/infrastructure/config/zones.tfvars.json new file mode 100644 index 0000000000..7356d40375 --- /dev/null +++ b/terraform/domains/infrastructure/config/zones.tfvars.json @@ -0,0 +1,11 @@ +{ + "hosted_zone": { + "claim-additional-teaching-payment.service.gov.uk": { + "caa_records": {}, + "txt_records": {}, + "resource_group_name": "s189p01-capt-dom-rg", + "front_door_name": "s189p01-capt-dom-fd" + } + }, + "deploy_default_records": false + } diff --git a/terraform/domains/infrastructure/config/zones_Terrafile b/terraform/domains/infrastructure/config/zones_Terrafile new file mode 100644 index 0000000000..58e60b3c88 --- /dev/null +++ b/terraform/domains/infrastructure/config/zones_Terrafile @@ -0,0 +1,3 @@ +domains: + source: "https://github.com/DFE-Digital/terraform-modules" + version: "stable" diff --git a/terraform/domains/infrastructure/main.tf b/terraform/domains/infrastructure/main.tf new file mode 100644 index 0000000000..da091f5e16 --- /dev/null +++ b/terraform/domains/infrastructure/main.tf @@ -0,0 +1,5 @@ +module "domains_infrastructure" { + source = "./vendor/modules/domains//domains/infrastructure" + hosted_zone = var.hosted_zone + deploy_default_records = var.deploy_default_records +} diff --git a/terraform/domains/infrastructure/terraform.tf b/terraform/domains/infrastructure/terraform.tf new file mode 100644 index 0000000000..9d635e850c --- /dev/null +++ b/terraform/domains/infrastructure/terraform.tf @@ -0,0 +1,19 @@ +terraform { + required_version = "= 1.8.4" + + required_providers { + azurerm = { + source = "hashicorp/azurerm" + version = "3.104.2" + } + } + backend "azurerm" { + container_name = "terraform-state" + } +} + +provider "azurerm" { + features {} + + skip_provider_registration = true +} diff --git a/terraform/domains/infrastructure/variables.tf b/terraform/domains/infrastructure/variables.tf new file mode 100644 index 0000000000..8d91472066 --- /dev/null +++ b/terraform/domains/infrastructure/variables.tf @@ -0,0 +1,7 @@ +variable "hosted_zone" { + type = map(any) +} + +variable "deploy_default_records" { + default = true +} From 5bab91977adbac05acef23b374f3d53debb3270c Mon Sep 17 00:00:00 2001 From: Felix Clack Date: Mon, 24 Jun 2024 09:53:27 +0100 Subject: [PATCH 46/66] Setup the admin to display IRP claims In order to be able to display the IRP claims in the admin, there are some basic methods that need to be available. This change ensures the minimum implementation for displaying claims without being concerned about the correctness of the required methods. Specifically the `award_amount` is a placeholder. In order to ensure we can successfully check for duplicate claims, I made an assumption that we would use passport number rather than teacher reference number as a unique identifier. I don't think claimants for IRP will have TRNs, therefore we need some other way of matching. We can change this assumption easily in the future but for now this allows us to ship the admin changes and keep moving forward. --- app/models/base_policy.rb | 4 +++ .../claim/claims_preventing_payment_finder.rb | 2 ++ app/models/claim_checking_tasks.rb | 4 +++ app/models/policies.rb | 3 +- .../international_relocation_payments.rb | 3 ++ .../admin_tasks_presenter.rb | 13 ++++++++ .../eligibility.rb | 9 ++++++ .../eligibility_admin_answers_presenter.rb | 28 +++++++++++++++++ config/locales/en.yml | 2 ++ spec/factories/journey_configurations.rb | 4 +++ .../eligibilities.rb | 13 ++++++++ spec/features/admin_claim_allocation_spec.rb | 30 +++++++++++++++---- spec/mailers/payment_mailer_spec.rb | 2 +- .../admin_tasks_presenter_spec.rb | 15 ++++++++++ ...ligibility_admin_answers_presenter_spec.rb | 13 ++++++++ spec/models/policies_spec.rb | 6 ++-- ...dmin_view_claim_feature_shared_examples.rb | 9 +++++- 17 files changed, 150 insertions(+), 10 deletions(-) create mode 100644 app/models/policies/international_relocation_payments/admin_tasks_presenter.rb create mode 100644 app/models/policies/international_relocation_payments/eligibility_admin_answers_presenter.rb create mode 100644 spec/models/policies/international_relocation_payments/admin_tasks_presenter_spec.rb create mode 100644 spec/models/policies/international_relocation_payments/eligibility_admin_answers_presenter_spec.rb diff --git a/app/models/base_policy.rb b/app/models/base_policy.rb index da9f4a0c42..a9a327a0be 100644 --- a/app/models/base_policy.rb +++ b/app/models/base_policy.rb @@ -46,4 +46,8 @@ def searchable_eligibility_attributes self::SEARCHABLE_ELIGIBILITY_ATTRIBUTES end + + def international_relocation_payments? + to_s == "InternationalRelocationPayments" + end end diff --git a/app/models/claim/claims_preventing_payment_finder.rb b/app/models/claim/claims_preventing_payment_finder.rb index 82be1248d9..d0f467962a 100644 --- a/app/models/claim/claims_preventing_payment_finder.rb +++ b/app/models/claim/claims_preventing_payment_finder.rb @@ -25,6 +25,8 @@ def claims_preventing_payment private def find_claims_preventing_payment + return [] if claim.policy == Policies::InternationalRelocationPayments + eligibility_ids = claim.policy.policies_claimable.map { |policy| policy::Eligibility.where(teacher_reference_number: claim.eligibility.teacher_reference_number) }.flatten.map(&:id) diff --git a/app/models/claim_checking_tasks.rb b/app/models/claim_checking_tasks.rb index 676e641e71..2fcdbc5620 100644 --- a/app/models/claim_checking_tasks.rb +++ b/app/models/claim_checking_tasks.rb @@ -9,7 +9,11 @@ def initialize(claim) @claim = claim end + delegate :policy, to: :claim + def applicable_task_names + return [] if policy.international_relocation_payments? + @applicable_task_names ||= Task::NAMES.dup.tap do |task_names| task_names.delete("induction_confirmation") unless claim.policy == Policies::EarlyCareerPayments task_names.delete("student_loan_amount") unless claim.policy == Policies::StudentLoans diff --git a/app/models/policies.rb b/app/models/policies.rb index c155fd43bf..d51f30fa9a 100644 --- a/app/models/policies.rb +++ b/app/models/policies.rb @@ -2,7 +2,8 @@ module Policies POLICIES = [ StudentLoans, EarlyCareerPayments, - LevellingUpPremiumPayments + LevellingUpPremiumPayments, + InternationalRelocationPayments ].freeze AMENDABLE_ELIGIBILITY_ATTRIBUTES = POLICIES.map do |policy| diff --git a/app/models/policies/international_relocation_payments.rb b/app/models/policies/international_relocation_payments.rb index 52d02a93ba..d66ed2c747 100644 --- a/app/models/policies/international_relocation_payments.rb +++ b/app/models/policies/international_relocation_payments.rb @@ -3,6 +3,9 @@ module InternationalRelocationPayments include BasePolicy extend self + ELIGIBILITY_MATCHING_ATTRIBUTES = [["passport_number"]].freeze + OTHER_CLAIMABLE_POLICIES = [] + # NOTE RL: currently IRP only has a single reply to address, so notify # doesn't show the address id def notify_reply_to_id diff --git a/app/models/policies/international_relocation_payments/admin_tasks_presenter.rb b/app/models/policies/international_relocation_payments/admin_tasks_presenter.rb new file mode 100644 index 0000000000..e50adb3676 --- /dev/null +++ b/app/models/policies/international_relocation_payments/admin_tasks_presenter.rb @@ -0,0 +1,13 @@ +module Policies + module InternationalRelocationPayments + class AdminTasksPresenter + include Admin::PresenterMethods + + attr_reader :claim + + def initialize(claim) + @claim = claim + end + end + end +end diff --git a/app/models/policies/international_relocation_payments/eligibility.rb b/app/models/policies/international_relocation_payments/eligibility.rb index c5f1b73414..b755ebb54f 100644 --- a/app/models/policies/international_relocation_payments/eligibility.rb +++ b/app/models/policies/international_relocation_payments/eligibility.rb @@ -3,7 +3,16 @@ module InternationalRelocationPayments class Eligibility < ApplicationRecord self.table_name = "international_relocation_payments_eligibilities" + AMENDABLE_ATTRIBUTES = %i[].freeze + has_one :claim, as: :eligibility, inverse_of: :eligibility + belongs_to :current_school, class_name: "School" + + attr_accessor :teacher_reference_number + + def award_amount + 0 + end def ineligible? false diff --git a/app/models/policies/international_relocation_payments/eligibility_admin_answers_presenter.rb b/app/models/policies/international_relocation_payments/eligibility_admin_answers_presenter.rb new file mode 100644 index 0000000000..977e4f6652 --- /dev/null +++ b/app/models/policies/international_relocation_payments/eligibility_admin_answers_presenter.rb @@ -0,0 +1,28 @@ +module Policies + module InternationalRelocationPayments + class EligibilityAdminAnswersPresenter + include Admin::PresenterMethods + + attr_reader :eligibility + + def initialize(eligibility) + @eligibility = eligibility + end + + def answers + [].tap do |a| + a << current_school + end + end + + private + + def current_school + [ + translate("admin.current_school"), + display_school(eligibility.current_school) + ] + end + end + end +end diff --git a/config/locales/en.yml b/config/locales/en.yml index 63e910cfb4..6ed377f046 100644 --- a/config/locales/en.yml +++ b/config/locales/en.yml @@ -770,6 +770,8 @@ en: "By selecting continue you are confirming that, to the best of your knowledge, the details you are providing are correct." international_relocation_payments: <<: *get_a_teacher_relocation_payment + policy_short_name: "International Relocation Payments" + policy_acronym: "IRP" further_education_payments: landing_page: Find out if you are eligible for any incentive payments for further education teachers diff --git a/spec/factories/journey_configurations.rb b/spec/factories/journey_configurations.rb index 0cc791d529..2212a19d64 100644 --- a/spec/factories/journey_configurations.rb +++ b/spec/factories/journey_configurations.rb @@ -14,6 +14,10 @@ routing_name { Journeys::GetATeacherRelocationPayment::ROUTING_NAME } end + trait :international_relocation_payments do + routing_name { Journeys::GetATeacherRelocationPayment::ROUTING_NAME } + end + trait :early_career_payments do additional_payments end diff --git a/spec/factories/policies/international_relocation_payments/eligibilities.rb b/spec/factories/policies/international_relocation_payments/eligibilities.rb index c1a58415af..305c19a952 100644 --- a/spec/factories/policies/international_relocation_payments/eligibilities.rb +++ b/spec/factories/policies/international_relocation_payments/eligibilities.rb @@ -1,4 +1,17 @@ FactoryBot.define do factory :international_relocation_payments_eligibility, class: "Policies::InternationalRelocationPayments::Eligibility" do + trait :eligible_home_office do + passport_number { "123456789" } + nationality { "French" } + end + + trait :eligible do + eligible_home_office + eligible_school + end + + trait :eligible_school do + association :current_school, factory: :school + end end end diff --git a/spec/features/admin_claim_allocation_spec.rb b/spec/features/admin_claim_allocation_spec.rb index d55e122cb4..d894dcccc0 100644 --- a/spec/features/admin_claim_allocation_spec.rb +++ b/spec/features/admin_claim_allocation_spec.rb @@ -4,6 +4,7 @@ before do create(:journey_configuration, :student_loans) create(:journey_configuration, :additional_payments) + create(:journey_configuration, :get_a_teacher_relocation_payment) submitted_claims = [] @signed_in_user = sign_in_as_service_operator @@ -29,6 +30,9 @@ # index: 35-38 submitted_claims << create_list(:claim, 4, :submitted, policy: Policies::LevellingUpPremiumPayments) + # index: 39 + submitted_claims << create_list(:claim, 1, :submitted, policy: Policies::InternationalRelocationPayments) + @submitted_claims = submitted_claims.flatten end @@ -60,6 +64,7 @@ let(:twenty_sixth_claim) { @submitted_claims[25] } let(:thirtieth_claim) { @submitted_claims[29] } let(:thirty_fifth_claim) { @submitted_claims[34] } + let(:thirty_ninth_claim) { @submitted_claims[38] } let(:student_loan_claims) do [ @@ -83,6 +88,8 @@ ].flatten end + let(:international_relocation_payment_claims) { [thirty_ninth_claim] } + let(:levelling_up_premium_payments) { @submitted_claims.slice(36...35) } let!(:sarah) { create(:dfe_signin_user, given_name: "Sarah", family_name: "Strawbridge", organisation_name: "Department for Education", role_codes: [DfeSignIn::User::SERVICE_OPERATOR_DFE_SIGN_IN_ROLE_CODE]) } @@ -97,11 +104,11 @@ within("#allocations") do expect(page).to have_select("allocate_to_team_member", options: ["Aaron Admin", "Sarah Strawbridge", "Frank Yee", "Abdul Rafiq"]) - expect(page).to have_select("allocate_to_policy", options: ["All", "Student Loans", "Early-Career Payments", "Levelling Up Premium Payments"]) + expect(page).to have_select("allocate_to_policy", options: ["All", "Student Loans", "Early-Career Payments", "Levelling Up Premium Payments", "International Relocation Payments"]) expect(page).to have_button("Allocate claims", disabled: false) expect(page).to have_button("Unallocate claims") end - expect(@submitted_claims.size).to eq 39 + expect(@submitted_claims.size).to eq 40 @submitted_claims.each do |claim| expect(claim.assigned_to).to be_nil @@ -152,7 +159,7 @@ within(".govuk-flash__notice") do expect(page).to have_text I18n.t( "admin.allocations.bulk_allocate.success", - quantity: 14, + quantity: 15, pluralized_or_singular_claim: "claims", allocate_to_policy: "", dfe_user: frank.full_name.titleize @@ -171,11 +178,11 @@ scenario "Student Loans" do click_on "View claims" - expect(@submitted_claims.size).to eq 39 + expect(@submitted_claims.size).to eq 40 within("#allocations") do expect(page).to have_select("allocate_to_team_member", options: ["Aaron Admin", "Sarah Strawbridge", "Frank Yee", "Abdul Rafiq"]) - expect(page).to have_select("allocate_to_policy", options: ["All", "Student Loans", "Early-Career Payments", "Levelling Up Premium Payments"]) + expect(page).to have_select("allocate_to_policy", options: ["All", "Student Loans", "Early-Career Payments", "Levelling Up Premium Payments", "International Relocation Payments"]) expect(page).to have_button("Allocate claims", disabled: false) expect(page).to have_button("Unallocate claims") end @@ -207,6 +214,19 @@ end end + scenario "International Relocation Payments" do + click_on "View claims" + + within("#allocations") do + expect(page).to have_select("allocate_to_team_member", options: ["Aaron Admin", "Sarah Strawbridge", "Frank Yee", "Abdul Rafiq"]) + expect(page).to have_select("allocate_to_policy", options: ["All", "Student Loans", "Early-Career Payments", "Levelling Up Premium Payments", "International Relocation Payments"]) + expect(page).to have_button("Allocate claims", disabled: false) + expect(page).to have_button("Unallocate claims") + end + + expect(thirty_ninth_claim.assigned_to).to be_nil + end + scenario "when no claims for specified policy awaiting assignment" do [ first_claim, diff --git a/spec/mailers/payment_mailer_spec.rb b/spec/mailers/payment_mailer_spec.rb index 90e3f04de0..60ebf2e3a4 100644 --- a/spec/mailers/payment_mailer_spec.rb +++ b/spec/mailers/payment_mailer_spec.rb @@ -16,7 +16,7 @@ end it "sets the GOV.UK Notify reply_to_id according to the policy" do - expect(mail["reply_to_id"].first.value).to eql(policy.notify_reply_to_id) + expect(mail["reply_to_id"]&.first&.value).to eql(policy.notify_reply_to_id) end it "mentions the type of claim in the subject" do diff --git a/spec/models/policies/international_relocation_payments/admin_tasks_presenter_spec.rb b/spec/models/policies/international_relocation_payments/admin_tasks_presenter_spec.rb new file mode 100644 index 0000000000..eb57c4e44f --- /dev/null +++ b/spec/models/policies/international_relocation_payments/admin_tasks_presenter_spec.rb @@ -0,0 +1,15 @@ +require "rails_helper" + +RSpec.describe Policies::InternationalRelocationPayments::AdminTasksPresenter, type: :model do + subject { presenter } + + let(:claim) { build(:claim, policy: Policies::InternationalRelocationPayments) } + let(:eligibility) { claim.eligibility } + let(:presenter) { described_class.new(claim) } + + describe "#claim" do + subject { presenter.claim } + + it { is_expected.to eq claim } + end +end diff --git a/spec/models/policies/international_relocation_payments/eligibility_admin_answers_presenter_spec.rb b/spec/models/policies/international_relocation_payments/eligibility_admin_answers_presenter_spec.rb new file mode 100644 index 0000000000..7dba901327 --- /dev/null +++ b/spec/models/policies/international_relocation_payments/eligibility_admin_answers_presenter_spec.rb @@ -0,0 +1,13 @@ +require "rails_helper" + +RSpec.describe Policies::InternationalRelocationPayments::EligibilityAdminAnswersPresenter, type: :model do + let(:claim) { build(:claim, :submittable, policy: Policies::InternationalRelocationPayments, academic_year: "2021/2022") } + + subject(:presenter) { described_class.new(claim.eligibility) } + + describe "#answers" do + it "returns an array of questions and answers for displaying to service operator" do + expect(presenter.answers).to eq [[I18n.t("admin.current_school"), presenter.display_school(claim.eligibility.current_school)]] + end + end +end diff --git a/spec/models/policies_spec.rb b/spec/models/policies_spec.rb index 9384573a53..3786b3c6da 100644 --- a/spec/models/policies_spec.rb +++ b/spec/models/policies_spec.rb @@ -6,7 +6,8 @@ expect(described_class::POLICIES).to eq([ Policies::StudentLoans, Policies::EarlyCareerPayments, - Policies::LevellingUpPremiumPayments + Policies::LevellingUpPremiumPayments, + Policies::InternationalRelocationPayments ]) end end @@ -30,7 +31,8 @@ expect(described_class.options_for_select).to eq([ ["Student Loans", "student-loans"], ["Early-Career Payments", "early-career-payments"], - ["Levelling Up Premium Payments", "levelling-up-premium-payments"] + ["Levelling Up Premium Payments", "levelling-up-premium-payments"], + ["International Relocation Payments", "international-relocation-payments"] ]) end end diff --git a/spec/support/admin_view_claim_feature_shared_examples.rb b/spec/support/admin_view_claim_feature_shared_examples.rb index 6a94d47da8..0e211b8b0b 100644 --- a/spec/support/admin_view_claim_feature_shared_examples.rb +++ b/spec/support/admin_view_claim_feature_shared_examples.rb @@ -34,7 +34,12 @@ } let!(:similar_claim) { - eligibility = create(:"#{policy.to_s.underscore}_eligibility", :eligible, teacher_reference_number: multiple_claim.eligibility.teacher_reference_number) + duplicate_attribute = if policy == Policies::InternationalRelocationPayments + {passport_number: multiple_claim.eligibility.passport_number} + else + {teacher_reference_number: multiple_claim.eligibility.teacher_reference_number} + end + eligibility = create(:"#{policy.to_s.underscore}_eligibility", :eligible, duplicate_attribute) create( :claim, :submitted, @@ -173,6 +178,8 @@ def expect_page_to_have_policy_sections(policy) ["Identity confirmation", "Qualifications", "Census subjects taught", "Employment", "Student loan plan", "Decision"] when Policies::EarlyCareerPayments ["Identity confirmation", "Qualifications", "Induction confirmation", "Census subjects taught", "Employment", "Student loan plan", "Decision"] + when Policies::InternationalRelocationPayments + ["Decision"] else raise "Unimplemented policy: #{policy}" end From 16bf14fe44ded51162e04366cc6ec5094a9eaeaa Mon Sep 17 00:00:00 2001 From: Felix Clack Date: Mon, 1 Jul 2024 07:42:19 +0100 Subject: [PATCH 47/66] Add the home office identity confirmation task for IRP THe first admin task for the IRP journey is verifying the Home Office identity check. We request the nationality and passport number for the individual submitting the claim and present that as the check for the admin task. --- app/models/claim_checking_tasks.rb | 2 +- .../admin_tasks_presenter.rb | 11 +++++++++++ config/locales/en.yml | 6 ++++++ spec/requests/admin_tasks_spec.rb | 12 ++++++++++++ .../admin_view_claim_feature_shared_examples.rb | 2 +- 5 files changed, 31 insertions(+), 2 deletions(-) diff --git a/app/models/claim_checking_tasks.rb b/app/models/claim_checking_tasks.rb index 2fcdbc5620..e00040e4dc 100644 --- a/app/models/claim_checking_tasks.rb +++ b/app/models/claim_checking_tasks.rb @@ -12,7 +12,7 @@ def initialize(claim) delegate :policy, to: :claim def applicable_task_names - return [] if policy.international_relocation_payments? + return ["identity_confirmation"] if policy.international_relocation_payments? @applicable_task_names ||= Task::NAMES.dup.tap do |task_names| task_names.delete("induction_confirmation") unless claim.policy == Policies::EarlyCareerPayments diff --git a/app/models/policies/international_relocation_payments/admin_tasks_presenter.rb b/app/models/policies/international_relocation_payments/admin_tasks_presenter.rb index e50adb3676..e64aa294ea 100644 --- a/app/models/policies/international_relocation_payments/admin_tasks_presenter.rb +++ b/app/models/policies/international_relocation_payments/admin_tasks_presenter.rb @@ -8,6 +8,17 @@ class AdminTasksPresenter def initialize(claim) @claim = claim end + + def identity_confirmation + [ + ["Nationality", eligibility.nationality], + ["Passport number", eligibility.passport_number] + ] + end + + private + + delegate :eligibility, to: :claim end end end diff --git a/config/locales/en.yml b/config/locales/en.yml index 6ed377f046..867a014da9 100644 --- a/config/locales/en.yml +++ b/config/locales/en.yml @@ -119,6 +119,8 @@ en: claim_route: "Claim route" claim_route_not_tid: "Not signed in with DfE Identity" claim_route_with_tid: "Signed in with DfE Identity" + passport_number: "Passport number" + nationality: "Nationality" decision: created_at: "Created at" result: "Result" @@ -772,6 +774,10 @@ en: <<: *get_a_teacher_relocation_payment policy_short_name: "International Relocation Payments" policy_acronym: "IRP" + admin: + task_questions: + identity_confirmation: + title: "Did %{claim_full_name} submit the claim?" further_education_payments: landing_page: Find out if you are eligible for any incentive payments for further education teachers diff --git a/spec/requests/admin_tasks_spec.rb b/spec/requests/admin_tasks_spec.rb index f47861a025..9c88e5cbc5 100644 --- a/spec/requests/admin_tasks_spec.rb +++ b/spec/requests/admin_tasks_spec.rb @@ -105,6 +105,18 @@ end end end + + context "with an International Relocation Payments claim" do + let(:claim) { create(:claim, :submitted, policy: Policies::InternationalRelocationPayments) } + + describe "tasks#show" do + it "renders the requested page" do + get admin_claim_task_path(claim, "identity_confirmation") + expect(response.body).to include(I18n.t("admin.nationality")) + expect(response.body).to include(I18n.t("admin.passport_number")) + end + end + end end context "when signed in as a payroll operator or a support agent" do diff --git a/spec/support/admin_view_claim_feature_shared_examples.rb b/spec/support/admin_view_claim_feature_shared_examples.rb index 0e211b8b0b..939e59cbcc 100644 --- a/spec/support/admin_view_claim_feature_shared_examples.rb +++ b/spec/support/admin_view_claim_feature_shared_examples.rb @@ -179,7 +179,7 @@ def expect_page_to_have_policy_sections(policy) when Policies::EarlyCareerPayments ["Identity confirmation", "Qualifications", "Induction confirmation", "Census subjects taught", "Employment", "Student loan plan", "Decision"] when Policies::InternationalRelocationPayments - ["Decision"] + ["Identity confirmation", "Decision"] else raise "Unimplemented policy: #{policy}" end From d1dc588b6c7f75967f79177bc2bfc2759e69ad82 Mon Sep 17 00:00:00 2001 From: Phil Lee Date: Tue, 25 Jun 2024 17:18:54 +0100 Subject: [PATCH 48/66] add academic start year form for FE journey --- ...ther_education_teaching_start_year_form.rb | 37 +++++++++++ .../journeys/further_education_payments.rb | 1 + .../session_answers.rb | 1 + .../slug_sequence.rb | 2 +- ...cademic_year_in_further_education.html.erb | 7 -- ...her_education_teaching_start_year.html.erb | 28 ++++++++ config/locales/en.yml | 3 + .../happy_js_path_spec.rb | 3 +- .../happy_path_spec.rb | 3 +- ...education_teaching_start_year_form_spec.rb | 66 +++++++++++++++++++ 10 files changed, 141 insertions(+), 10 deletions(-) create mode 100644 app/forms/journeys/further_education_payments/further_education_teaching_start_year_form.rb delete mode 100644 app/views/further_education_payments/claims/academic_year_in_further_education.html.erb create mode 100644 app/views/further_education_payments/claims/further_education_teaching_start_year.html.erb create mode 100644 spec/forms/journeys/further_education_payments/further_education_teaching_start_year_form_spec.rb diff --git a/app/forms/journeys/further_education_payments/further_education_teaching_start_year_form.rb b/app/forms/journeys/further_education_payments/further_education_teaching_start_year_form.rb new file mode 100644 index 0000000000..9f0a1031d7 --- /dev/null +++ b/app/forms/journeys/further_education_payments/further_education_teaching_start_year_form.rb @@ -0,0 +1,37 @@ +module Journeys + module FurtherEducationPayments + class FurtherEducationTeachingStartYearForm < Form + attribute :further_education_teaching_start_year, :string + + validates :further_education_teaching_start_year, + presence: {message: i18n_error_message(:blank)} + + def radio_options + years_before = -4 + + array = (years_before..0).map do |delta| + academic_year = AcademicYear.current + delta + OpenStruct.new( + id: academic_year.start_year.to_s, + name: "September #{academic_year.start_year} to August #{academic_year.end_year}" + ) + end + + academic_year = AcademicYear.current + years_before + array << OpenStruct.new( + id: "pre-#{academic_year.start_year}", + name: "I started before September #{academic_year.start_year}" + ) + + array + end + + def save + return false if invalid? + + journey_session.answers.assign_attributes(further_education_teaching_start_year:) + journey_session.save! + end + end + end +end diff --git a/app/models/journeys/further_education_payments.rb b/app/models/journeys/further_education_payments.rb index 1ff183dfe7..786e4b5e13 100644 --- a/app/models/journeys/further_education_payments.rb +++ b/app/models/journeys/further_education_payments.rb @@ -13,6 +13,7 @@ module FurtherEducationPayments "further-education-provision-search" => FurtherEducationProvisionSearchForm, "select-provision" => SelectProvisionForm, "contract-type" => ContractTypeForm, + "further-education-teaching-start-year" => FurtherEducationTeachingStartYearForm, "subjects-taught" => SubjectsTaughtForm } } diff --git a/app/models/journeys/further_education_payments/session_answers.rb b/app/models/journeys/further_education_payments/session_answers.rb index 4210d73a3b..5a52354cba 100644 --- a/app/models/journeys/further_education_payments/session_answers.rb +++ b/app/models/journeys/further_education_payments/session_answers.rb @@ -5,6 +5,7 @@ class SessionAnswers < Journeys::SessionAnswers attribute :provision_search, :string attribute :school_id, :string # GUID attribute :contract_type, :string + attribute :further_education_teaching_start_year, :string attribute :subjects_taught, default: [] def school diff --git a/app/models/journeys/further_education_payments/slug_sequence.rb b/app/models/journeys/further_education_payments/slug_sequence.rb index d9f41f5322..9565581810 100644 --- a/app/models/journeys/further_education_payments/slug_sequence.rb +++ b/app/models/journeys/further_education_payments/slug_sequence.rb @@ -7,7 +7,7 @@ class SlugSequence select-provision contract-type teaching-hours-per-week - academic-year-in-further-education + further-education-teaching-start-year subjects-taught building-and-construction-courses teaching-courses diff --git a/app/views/further_education_payments/claims/academic_year_in_further_education.html.erb b/app/views/further_education_payments/claims/academic_year_in_further_education.html.erb deleted file mode 100644 index 1c019f5e01..0000000000 --- a/app/views/further_education_payments/claims/academic_year_in_further_education.html.erb +++ /dev/null @@ -1,7 +0,0 @@ -

- FE academic year in further education goes here -

- -<%= form_with model: @form, url: claim_path(current_journey_routing_name), method: :patch, builder: GOVUKDesignSystemFormBuilder::FormBuilder, html: { novalidate: false } do |f| %> - <%= f.govuk_submit %> -<% end %> diff --git a/app/views/further_education_payments/claims/further_education_teaching_start_year.html.erb b/app/views/further_education_payments/claims/further_education_teaching_start_year.html.erb new file mode 100644 index 0000000000..364f22ef09 --- /dev/null +++ b/app/views/further_education_payments/claims/further_education_teaching_start_year.html.erb @@ -0,0 +1,28 @@ +
+
+ <%= form_with model: @form, url: claim_path(current_journey_routing_name), method: :patch, builder: GOVUKDesignSystemFormBuilder::FormBuilder, html: { novalidate: false } do |f| %> + <%= f.govuk_error_summary %> + + <%= f.govuk_radio_buttons_fieldset :further_education_teaching_start_year, + legend: { + text: "Which academic year did you start teaching in further education (FE) in England?", + tag: "h1", + size: "l" + } do %> + <% @form.radio_options[0..-2].each do |option| %> + <%= f.govuk_radio_button :further_education_teaching_start_year, option.id, + label: { text: option.name }, + link_errors: @form.radio_options.first == option %> + <% end %> + + <%= f.govuk_radio_divider %> + + <% option = @form.radio_options.last %> + <%= f.govuk_radio_button :further_education_teaching_start_year, option.id, + label: { text: option.name } %> + <% end %> + + <%= f.govuk_submit %> + <% end %> +
+
diff --git a/config/locales/en.yml b/config/locales/en.yml index 867a014da9..b47d0b3421 100644 --- a/config/locales/en.yml +++ b/config/locales/en.yml @@ -800,6 +800,9 @@ en: question: What type of contract do you have with %{school_name}? errors: inclusion: Select the contract type you have + further_education_teaching_start_year: + errors: + blank: Select which academic year you started teaching in further education in England subjects_taught: question: Which subject areas do you teach? hint: Select all that apply diff --git a/spec/features/further_education_payments/happy_js_path_spec.rb b/spec/features/further_education_payments/happy_js_path_spec.rb index 11c728af8d..b983e2fdaf 100644 --- a/spec/features/further_education_payments/happy_js_path_spec.rb +++ b/spec/features/further_education_payments/happy_js_path_spec.rb @@ -33,7 +33,8 @@ expect(page).to have_content("FE teaching hours per week goes here") click_button "Continue" - expect(page).to have_content("FE academic year in further education goes here") + expect(page).to have_content("Which academic year did you start teaching in further education (FE) in England?") + choose("September 2023 to August 2024") click_button "Continue" expect(page).to have_content("Which subject areas do you teach?") diff --git a/spec/features/further_education_payments/happy_path_spec.rb b/spec/features/further_education_payments/happy_path_spec.rb index 7e38c5c95b..3329e7e20a 100644 --- a/spec/features/further_education_payments/happy_path_spec.rb +++ b/spec/features/further_education_payments/happy_path_spec.rb @@ -30,7 +30,8 @@ expect(page).to have_content("FE teaching hours per week goes here") click_button "Continue" - expect(page).to have_content("FE academic year in further education goes here") + expect(page).to have_content("Which academic year did you start teaching in further education (FE) in England?") + choose("September 2023 to August 2024") click_button "Continue" expect(page).to have_content("Which subject areas do you teach?") diff --git a/spec/forms/journeys/further_education_payments/further_education_teaching_start_year_form_spec.rb b/spec/forms/journeys/further_education_payments/further_education_teaching_start_year_form_spec.rb new file mode 100644 index 0000000000..cdd8503fa5 --- /dev/null +++ b/spec/forms/journeys/further_education_payments/further_education_teaching_start_year_form_spec.rb @@ -0,0 +1,66 @@ +require "rails_helper" + +RSpec.describe Journeys::FurtherEducationPayments::FurtherEducationTeachingStartYearForm, type: :model do + let(:journey) { Journeys::FurtherEducationPayments } + let(:journey_session) { create(:further_education_payments_session) } + let(:further_education_teaching_start_year) { nil } + + let(:params) do + ActionController::Parameters.new( + claim: { + further_education_teaching_start_year: + } + ) + end + + subject do + described_class.new( + journey_session:, + journey:, + params: + ) + end + + describe "#radio_options" do + it "returns 6 options" do + expect(subject.radio_options.size).to eql(6) + end + + it "returns expected data" do + travel_to Time.zone.local(2024, 12, 1) do + expected = [ + OpenStruct.new(id: "2020", name: "September 2020 to August 2021"), + OpenStruct.new(id: "2021", name: "September 2021 to August 2022"), + OpenStruct.new(id: "2022", name: "September 2022 to August 2023"), + OpenStruct.new(id: "2023", name: "September 2023 to August 2024"), + OpenStruct.new(id: "2024", name: "September 2024 to August 2025"), + OpenStruct.new(id: "pre-2020", name: "I started before September 2020") + ] + + expect(subject.radio_options).to eql(expected) + end + end + end + + describe "validations" do + let(:further_education_teaching_start_year) { nil } + + it do + is_expected.not_to( + allow_value(further_education_teaching_start_year) + .for(:further_education_teaching_start_year) + .with_message("Select which academic year you started teaching in further education in England") + ) + end + end + + describe "#save" do + let(:further_education_teaching_start_year) { AcademicYear.current.start_year.to_s } + + it "updates the journey session" do + expect { expect(subject.save).to be(true) }.to( + change { journey_session.reload.answers.further_education_teaching_start_year }.to(further_education_teaching_start_year) + ) + end + end +end From 1a378d85e335fed47f2d04539e5c66ec34fdfb25 Mon Sep 17 00:00:00 2001 From: Phil Lee Date: Wed, 26 Jun 2024 15:31:38 +0100 Subject: [PATCH 49/66] add teaching hours per week to FE journey --- .../teaching_hours_per_week_form.rb | 34 +++++++++++++ .../journeys/further_education_payments.rb | 1 + .../session_answers.rb | 1 + .../claims/teaching_hours_per_week.html.erb | 22 +++++--- config/locales/en.yml | 5 ++ ... => further_education_payments_answers.rb} | 0 .../happy_js_path_spec.rb | 3 +- .../happy_path_spec.rb | 3 +- .../teaching_hours_per_week_form_spec.rb | 50 +++++++++++++++++++ 9 files changed, 111 insertions(+), 8 deletions(-) create mode 100644 app/forms/journeys/further_education_payments/teaching_hours_per_week_form.rb rename spec/factories/journeys/further_education_payments/{session_answers.rb => further_education_payments_answers.rb} (100%) create mode 100644 spec/forms/journeys/further_education_payments/teaching_hours_per_week_form_spec.rb diff --git a/app/forms/journeys/further_education_payments/teaching_hours_per_week_form.rb b/app/forms/journeys/further_education_payments/teaching_hours_per_week_form.rb new file mode 100644 index 0000000000..4fab25abd8 --- /dev/null +++ b/app/forms/journeys/further_education_payments/teaching_hours_per_week_form.rb @@ -0,0 +1,34 @@ +module Journeys + module FurtherEducationPayments + class TeachingHoursPerWeekForm < Form + attribute :teaching_hours_per_week, :string + + validates :teaching_hours_per_week, + inclusion: {in: ->(form) { form.radio_options.map(&:id) }, message: i18n_error_message(:inclusion)} + + def radio_options + @radio_options ||= [ + OpenStruct.new( + id: "more-than-12", + name: "More than 12 hours per week" + ), + OpenStruct.new( + id: "between-2.5-and-12", + name: "Between 2.5 and 12 hours per week" + ), + OpenStruct.new( + id: "less-than-2.5", + name: "Less than 2.5 hours per week" + ) + ] + end + + def save + return false unless valid? + + journey_session.answers.assign_attributes(teaching_hours_per_week:) + journey_session.save! + end + end + end +end diff --git a/app/models/journeys/further_education_payments.rb b/app/models/journeys/further_education_payments.rb index 786e4b5e13..1705beb167 100644 --- a/app/models/journeys/further_education_payments.rb +++ b/app/models/journeys/further_education_payments.rb @@ -13,6 +13,7 @@ module FurtherEducationPayments "further-education-provision-search" => FurtherEducationProvisionSearchForm, "select-provision" => SelectProvisionForm, "contract-type" => ContractTypeForm, + "teaching-hours-per-week" => TeachingHoursPerWeekForm, "further-education-teaching-start-year" => FurtherEducationTeachingStartYearForm, "subjects-taught" => SubjectsTaughtForm } diff --git a/app/models/journeys/further_education_payments/session_answers.rb b/app/models/journeys/further_education_payments/session_answers.rb index 5a52354cba..3921902e17 100644 --- a/app/models/journeys/further_education_payments/session_answers.rb +++ b/app/models/journeys/further_education_payments/session_answers.rb @@ -5,6 +5,7 @@ class SessionAnswers < Journeys::SessionAnswers attribute :provision_search, :string attribute :school_id, :string # GUID attribute :contract_type, :string + attribute :teaching_hours_per_week, :string attribute :further_education_teaching_start_year, :string attribute :subjects_taught, default: [] diff --git a/app/views/further_education_payments/claims/teaching_hours_per_week.html.erb b/app/views/further_education_payments/claims/teaching_hours_per_week.html.erb index 5e6ea94952..f8592511e5 100644 --- a/app/views/further_education_payments/claims/teaching_hours_per_week.html.erb +++ b/app/views/further_education_payments/claims/teaching_hours_per_week.html.erb @@ -1,7 +1,17 @@ -

- FE teaching hours per week goes here -

+
+
+ <%= form_with model: @form, url: claim_path(current_journey_routing_name), method: :patch, builder: GOVUKDesignSystemFormBuilder::FormBuilder, html: { novalidate: false } do |f| %> + <%= f.govuk_error_summary %> -<%= form_with model: @form, url: claim_path(current_journey_routing_name), method: :patch, builder: GOVUKDesignSystemFormBuilder::FormBuilder, html: { novalidate: false } do |f| %> - <%= f.govuk_submit %> -<% end %> + <%= f.govuk_collection_radio_buttons :teaching_hours_per_week, @form.radio_options, :id, :name, + legend: { + text: @form.t(:question, school_name: journey_session.answers.school.name), + tag: "h1", + size: "l" + }, + hint: { text: @form.t(:hint) } %> + + <%= f.govuk_submit %> + <% end %> +
+
diff --git a/config/locales/en.yml b/config/locales/en.yml index b47d0b3421..3100758e5c 100644 --- a/config/locales/en.yml +++ b/config/locales/en.yml @@ -800,6 +800,11 @@ en: question: What type of contract do you have with %{school_name}? errors: inclusion: Select the contract type you have + teaching_hours_per_week: + question: On average, how many hours per week are you timetabled to teach at %{school_name} during the current term? + hint: ‘Teaching’ refers to the direct contact time you spend in lessons with students of all ages. + errors: + inclusion: Select how many hours per week you are timetabled to teach during the current term further_education_teaching_start_year: errors: blank: Select which academic year you started teaching in further education in England diff --git a/spec/factories/journeys/further_education_payments/session_answers.rb b/spec/factories/journeys/further_education_payments/further_education_payments_answers.rb similarity index 100% rename from spec/factories/journeys/further_education_payments/session_answers.rb rename to spec/factories/journeys/further_education_payments/further_education_payments_answers.rb diff --git a/spec/features/further_education_payments/happy_js_path_spec.rb b/spec/features/further_education_payments/happy_js_path_spec.rb index b983e2fdaf..002d6b9856 100644 --- a/spec/features/further_education_payments/happy_js_path_spec.rb +++ b/spec/features/further_education_payments/happy_js_path_spec.rb @@ -30,7 +30,8 @@ choose("Permanent contract") click_button "Continue" - expect(page).to have_content("FE teaching hours per week goes here") + expect(page).to have_content("On average, how many hours per week are you timetabled to teach at #{college.name} during the current term?") + choose("More than 12 hours per week") click_button "Continue" expect(page).to have_content("Which academic year did you start teaching in further education (FE) in England?") diff --git a/spec/features/further_education_payments/happy_path_spec.rb b/spec/features/further_education_payments/happy_path_spec.rb index 3329e7e20a..75d2ae0e99 100644 --- a/spec/features/further_education_payments/happy_path_spec.rb +++ b/spec/features/further_education_payments/happy_path_spec.rb @@ -27,7 +27,8 @@ choose("Permanent contract") click_button "Continue" - expect(page).to have_content("FE teaching hours per week goes here") + expect(page).to have_content("On average, how many hours per week are you timetabled to teach at #{college.name} during the current term?") + choose("More than 12 hours per week") click_button "Continue" expect(page).to have_content("Which academic year did you start teaching in further education (FE) in England?") diff --git a/spec/forms/journeys/further_education_payments/teaching_hours_per_week_form_spec.rb b/spec/forms/journeys/further_education_payments/teaching_hours_per_week_form_spec.rb new file mode 100644 index 0000000000..e0014504ea --- /dev/null +++ b/spec/forms/journeys/further_education_payments/teaching_hours_per_week_form_spec.rb @@ -0,0 +1,50 @@ +require "rails_helper" + +RSpec.describe Journeys::FurtherEducationPayments::TeachingHoursPerWeekForm, type: :model do + let(:journey) { Journeys::FurtherEducationPayments } + let(:journey_session) { create(:further_education_payments_session, answers:) } + let(:answers) { build(:further_education_payments_answers, answers_hash) } + let(:college) { create(:school) } + let(:answers_hash) do + {school_id: college.id} + end + let(:teaching_hours_per_week) { nil } + + let(:params) do + ActionController::Parameters.new( + claim: { + teaching_hours_per_week: + } + ) + end + + subject do + described_class.new( + journey_session:, + journey:, + params: + ) + end + + describe "validations" do + let(:teaching_hours_per_week) { nil } + + it do + is_expected.not_to( + allow_value(nil) + .for(:teaching_hours_per_week) + .with_message("Select how many hours per week you are timetabled to teach during the current term") + ) + end + end + + describe "#save" do + let(:teaching_hours_per_week) { "more-than-12" } + + it "updates the journey session" do + expect { expect(subject.save).to be(true) }.to( + change { journey_session.reload.answers.teaching_hours_per_week }.to(teaching_hours_per_week) + ) + end + end +end From f39ab4eac9d575cf07b2372553b55cb8df9f633a Mon Sep 17 00:00:00 2001 From: Richard Lynch Date: Mon, 1 Jul 2024 11:48:15 +0100 Subject: [PATCH 50/66] Purge unsubmitted journey sessions Now we only create a claim once the claimant has completed the journey we need to update the purge job to work on journey sessions rather than claims as all claims are submitted claims. --- app/jobs/purge_unsubmitted_claims_job.rb | 8 ++--- app/models/journeys/session.rb | 8 +++++ .../jobs/purge_unsubmitted_claims_job_spec.rb | 32 +++++++++++++++---- 3 files changed, 38 insertions(+), 10 deletions(-) diff --git a/app/jobs/purge_unsubmitted_claims_job.rb b/app/jobs/purge_unsubmitted_claims_job.rb index bd8125903f..27404e92e5 100644 --- a/app/jobs/purge_unsubmitted_claims_job.rb +++ b/app/jobs/purge_unsubmitted_claims_job.rb @@ -5,13 +5,13 @@ class PurgeUnsubmittedClaimsJob < CronJob self.cron_expression = "0 0 * * *" def perform - Rails.logger.info "Purging #{old_unsubmitted_claims.count} old and unsubmitted claims from the database" - old_unsubmitted_claims.destroy_all + Rails.logger.info "Purging #{old_unsubmitted_journeys.count} old and unsubmitted journeys from the database" + old_unsubmitted_journeys.destroy_all end private - def old_unsubmitted_claims - Claim.unsubmitted.where("updated_at < ?", 24.hours.ago) + def old_unsubmitted_journeys + Journeys::Session.purgeable end end diff --git a/app/models/journeys/session.rb b/app/models/journeys/session.rb index ed2c1cc5a3..1774efb851 100644 --- a/app/models/journeys/session.rb +++ b/app/models/journeys/session.rb @@ -2,6 +2,8 @@ module Journeys class Session < ApplicationRecord self.abstract_class = true + self.table_name = "journeys_sessions" + has_one :claim, dependent: :nullify, inverse_of: :journey_session, @@ -11,6 +13,12 @@ class Session < ApplicationRecord presence: true, inclusion: {in: Journeys.all_routing_names} + scope :unsubmitted, -> { where.missing(:claim) } + + scope :purgeable, -> do + unsubmitted.where(journeys_sessions: {updated_at: ..24.hours.ago}) + end + def submitted? claim.present? end diff --git a/spec/jobs/purge_unsubmitted_claims_job_spec.rb b/spec/jobs/purge_unsubmitted_claims_job_spec.rb index 2d534777c2..050b7efc0f 100644 --- a/spec/jobs/purge_unsubmitted_claims_job_spec.rb +++ b/spec/jobs/purge_unsubmitted_claims_job_spec.rb @@ -6,17 +6,37 @@ let(:four_hours_ago) { 4.hours.ago } it "destroys any unsubmitted claims that have not been updated in the last 24 hours" do - expired_unsubmitted_claim = create(:claim, updated_at: over_24_hours_ago) - active_unsubmitted_claim = create(:claim, updated_at: four_hours_ago) + submitted_journeys = [] + unsubmitted_fresh_journeys = [] + unsubmitted_expired_journeys = [] - old_submitted_claim = create(:claim, :submitted, updated_at: over_24_hours_ago) + Journeys::JOURNEYS.each do |journey| + submitted_journeys << journey::Session.create!( + journey: journey::ROUTING_NAME, + claim: create(:claim), + updated_at: over_24_hours_ago + ) + + unsubmitted_fresh_journeys << journey::Session.create!( + journey: journey::ROUTING_NAME, + updated_at: four_hours_ago + ) + + unsubmitted_expired_journeys << journey::Session.create!( + journey: journey::ROUTING_NAME, + updated_at: over_24_hours_ago + ) + end PurgeUnsubmittedClaimsJob.new.perform - expect(Claim.exists?(expired_unsubmitted_claim.id)).to eq false + expect(submitted_journeys.each(&:reload)).to all be_persisted + + expect(unsubmitted_fresh_journeys.each(&:reload)).to all be_persisted - expect(Claim.exists?(old_submitted_claim.id)).to eq true - expect(Claim.exists?(active_unsubmitted_claim.id)).to eq true + expect( + Journeys::Session.where(id: unsubmitted_expired_journeys.map(&:id)) + ).to be_empty end end end From 1e36529e7ae4cf2e9bab60739ec00994f1991cbd Mon Sep 17 00:00:00 2001 From: Richard Lynch Date: Fri, 28 Jun 2024 15:37:27 +0100 Subject: [PATCH 51/66] Make below_min_qa_threshold an instance method This method is only used in one place, in an instance method on Claim, so it doesn't need to be a class method. By moving this method to be an instance method it will be easier to overwrite the MIN_QA_THRESHOLD on a per policy basis. --- app/models/claim.rb | 52 +++++++++++++++++++-------------------- spec/models/claim_spec.rb | 8 +++--- 2 files changed, 30 insertions(+), 30 deletions(-) diff --git a/app/models/claim.rb b/app/models/claim.rb index 625b7b2f22..304e4bce68 100644 --- a/app/models/claim.rb +++ b/app/models/claim.rb @@ -181,31 +181,6 @@ class Claim < ApplicationRecord scope :awaiting_qa, -> { approved.qa_required.where(qa_completed_at: nil) } scope :qa_required, -> { where(qa_required: true) } - # This method's intention is to help make a decision on whether a claim should - # be flagged for QA or not. These criteria need to be met for each academic year: - # - # 1. the first claim to be approved should always be flagged for QA - # 2. subsequently approved claims should be flagged for QA, 1 in 100/MIN_QA_THRESHOLD. - # - # This method should be used every time a new approval decision is being made; - # when used retrospectively, i.e. when several claims have been approved, - # the method returns: - # - # 1. `true` if none of then claims have been flagged for QA - # 2. `true` if some claims have been flagged for QA using a lower MIN_QA_THRESHOLD - # 3. `false` if some claims have been flagged for QA using a higher MIN_QA_THRESHOLD - # - # Newly approved claims should not be flagged for QA for as long as the method - # returns `false`; they should be flagged for QA otherwise. - def self.below_min_qa_threshold? - return false if MIN_QA_THRESHOLD.zero? - - claims_approved_so_far = current_academic_year.approved.count - return true if claims_approved_so_far.zero? - - (current_academic_year.approved.qa_required.count.to_f / claims_approved_so_far) * 100 <= MIN_QA_THRESHOLD - end - def hold!(reason:, user:) if holdable? && !held? self.class.transaction do @@ -245,7 +220,32 @@ def holdable? end def flaggable_for_qa? - decision_made? && latest_decision.approved? && Claim.below_min_qa_threshold? && !awaiting_qa? && !qa_completed? + decision_made? && latest_decision.approved? && below_min_qa_threshold? && !awaiting_qa? && !qa_completed? + end + + # This method's intention is to help make a decision on whether a claim should + # be flagged for QA or not. These criteria need to be met for each academic year: + # + # 1. the first claim to be approved should always be flagged for QA + # 2. subsequently approved claims should be flagged for QA, 1 in 100/MIN_QA_THRESHOLD. + # + # This method should be used every time a new approval decision is being made; + # when used retrospectively, i.e. when several claims have been approved, + # the method returns: + # + # 1. `true` if none of then claims have been flagged for QA + # 2. `true` if some claims have been flagged for QA using a lower MIN_QA_THRESHOLD + # 3. `false` if some claims have been flagged for QA using a higher MIN_QA_THRESHOLD + # + # Newly approved claims should not be flagged for QA for as long as the method + # returns `false`; they should be flagged for QA otherwise. + def below_min_qa_threshold? + return false if MIN_QA_THRESHOLD.zero? + + claims_approved_so_far = Claim.current_academic_year.approved.count + return true if claims_approved_so_far.zero? + + (Claim.current_academic_year.approved.qa_required.count.to_f / claims_approved_so_far) * 100 <= MIN_QA_THRESHOLD end def qa_completed? diff --git a/spec/models/claim_spec.rb b/spec/models/claim_spec.rb index ef5c807cab..75897302b5 100644 --- a/spec/models/claim_spec.rb +++ b/spec/models/claim_spec.rb @@ -371,7 +371,7 @@ context "when above the min QA threshold" do before do - allow(Claim).to receive(:below_min_qa_threshold?).and_return(false) + stub_const("Claim::MIN_QA_THRESHOLD", 0) end it { is_expected.to eq(false) } @@ -379,7 +379,7 @@ context "when below the min QA threshold" do before do - allow(Claim).to receive(:below_min_qa_threshold?).and_return(true) + stub_const("Claim::MIN_QA_THRESHOLD", 100) end it { is_expected.to eq(true) } @@ -597,8 +597,8 @@ end end - describe ".below_min_qa_threshold?" do - subject { described_class.below_min_qa_threshold? } + describe "#below_min_qa_threshold?" do + subject { described_class.new.below_min_qa_threshold? } context "when the MIN_QA_THRESHOLD is set to zero" do before do From af1611b128c2f317f131a525a63731dd24470ade Mon Sep 17 00:00:00 2001 From: Richard Lynch Date: Fri, 28 Jun 2024 17:07:13 +0100 Subject: [PATCH 52/66] Set QA threshold per policy Previously we were QAing 10% of all claims when what we want to do is QA 10% of claims for each policy. This commit moves the MIN_QA_THRESHOLD constant into the policy such that it's configurable on a per policy basis. --- app/models/claim.rb | 7 +- app/models/policies/early_career_payments.rb | 3 + .../policies/further_education_payments.rb | 2 + .../international_relocation_payments.rb | 3 + .../policies/levelling_up_premium_payments.rb | 3 + app/models/policies/student_loans.rb | 3 + spec/models/claim_spec.rb | 178 ++++++++++++++++-- spec/support/stubbing_helpers.rb | 4 +- 8 files changed, 182 insertions(+), 21 deletions(-) diff --git a/app/models/claim.rb b/app/models/claim.rb index 304e4bce68..41517119b2 100644 --- a/app/models/claim.rb +++ b/app/models/claim.rb @@ -1,7 +1,6 @@ # frozen_string_literal: true class Claim < ApplicationRecord - MIN_QA_THRESHOLD = 10 NO_STUDENT_LOAN = "not_applicable" STUDENT_LOAN_PLAN_OPTIONS = StudentLoan::PLANS.dup << NO_STUDENT_LOAN ADDRESS_ATTRIBUTES = %w[address_line_1 address_line_2 address_line_3 address_line_4 postcode].freeze @@ -240,12 +239,12 @@ def flaggable_for_qa? # Newly approved claims should not be flagged for QA for as long as the method # returns `false`; they should be flagged for QA otherwise. def below_min_qa_threshold? - return false if MIN_QA_THRESHOLD.zero? + return false if policy::MIN_QA_THRESHOLD.zero? - claims_approved_so_far = Claim.current_academic_year.approved.count + claims_approved_so_far = Claim.by_policy(policy).current_academic_year.approved.count return true if claims_approved_so_far.zero? - (Claim.current_academic_year.approved.qa_required.count.to_f / claims_approved_so_far) * 100 <= MIN_QA_THRESHOLD + (Claim.by_policy(policy).current_academic_year.approved.qa_required.count.to_f / claims_approved_so_far) * 100 <= policy::MIN_QA_THRESHOLD end def qa_completed? diff --git a/app/models/policies/early_career_payments.rb b/app/models/policies/early_career_payments.rb index 8d6bffbe94..1f6569aa95 100644 --- a/app/models/policies/early_career_payments.rb +++ b/app/models/policies/early_career_payments.rb @@ -37,6 +37,9 @@ module EarlyCareerPayments SEARCHABLE_ELIGIBILITY_ATTRIBUTES = %w[teacher_reference_number].freeze + # Percentage of claims to QA + MIN_QA_THRESHOLD = 10 + def eligibility_page_url "https://www.gov.uk/guidance/early-career-payments-guidance-for-teachers-and-schools" end diff --git a/app/models/policies/further_education_payments.rb b/app/models/policies/further_education_payments.rb index 7aa3fb3edf..2e526c6f07 100644 --- a/app/models/policies/further_education_payments.rb +++ b/app/models/policies/further_education_payments.rb @@ -1,4 +1,6 @@ module Policies module FurtherEducationPayments + # Percentage of claims to QA + MIN_QA_THRESHOLD = 10 end end diff --git a/app/models/policies/international_relocation_payments.rb b/app/models/policies/international_relocation_payments.rb index d66ed2c747..e0acd520bb 100644 --- a/app/models/policies/international_relocation_payments.rb +++ b/app/models/policies/international_relocation_payments.rb @@ -6,6 +6,9 @@ module InternationalRelocationPayments ELIGIBILITY_MATCHING_ATTRIBUTES = [["passport_number"]].freeze OTHER_CLAIMABLE_POLICIES = [] + # Percentage of claims to QA + MIN_QA_THRESHOLD = 10 + # NOTE RL: currently IRP only has a single reply to address, so notify # doesn't show the address id def notify_reply_to_id diff --git a/app/models/policies/levelling_up_premium_payments.rb b/app/models/policies/levelling_up_premium_payments.rb index 052fa437bb..69837d6308 100644 --- a/app/models/policies/levelling_up_premium_payments.rb +++ b/app/models/policies/levelling_up_premium_payments.rb @@ -27,6 +27,9 @@ module LevellingUpPremiumPayments POLICY_START_YEAR = AcademicYear.new(2022).freeze POLICY_END_YEAR = AcademicYear.new(2024).freeze + # Percentage of claims to QA + MIN_QA_THRESHOLD = 10 + def notify_reply_to_id "03ece7eb-2a5b-461b-9c91-6630d0051aa6" end diff --git a/app/models/policies/student_loans.rb b/app/models/policies/student_loans.rb index a39eda968a..71006ed7d9 100644 --- a/app/models/policies/student_loans.rb +++ b/app/models/policies/student_loans.rb @@ -37,6 +37,9 @@ module StudentLoans SEARCHABLE_ELIGIBILITY_ATTRIBUTES = %w[teacher_reference_number].freeze + # Percentage of claims to QA + MIN_QA_THRESHOLD = 10 + def eligibility_page_url "https://www.gov.uk/guidance/teachers-claim-back-your-student-loan-repayments" end diff --git a/spec/models/claim_spec.rb b/spec/models/claim_spec.rb index 75897302b5..ba2eca6132 100644 --- a/spec/models/claim_spec.rb +++ b/spec/models/claim_spec.rb @@ -371,7 +371,7 @@ context "when above the min QA threshold" do before do - stub_const("Claim::MIN_QA_THRESHOLD", 0) + stub_const("Policies::#{claim.policy}::MIN_QA_THRESHOLD", 0) end it { is_expected.to eq(false) } @@ -379,7 +379,7 @@ context "when below the min QA threshold" do before do - stub_const("Claim::MIN_QA_THRESHOLD", 100) + stub_const("Policies::#{claim.policy}::MIN_QA_THRESHOLD", 100) end it { is_expected.to eq(true) } @@ -598,11 +598,14 @@ end describe "#below_min_qa_threshold?" do - subject { described_class.new.below_min_qa_threshold? } + let(:policy) { Policies::EarlyCareerPayments } + let(:other_policy) { Policies::POLICIES.detect { |p| p != policy } } + + subject { build(:claim, policy: policy).below_min_qa_threshold? } context "when the MIN_QA_THRESHOLD is set to zero" do before do - stub_const("Claim::MIN_QA_THRESHOLD", 0) + stub_const("Policies::#{policy}::MIN_QA_THRESHOLD", 0) end it { is_expected.to eq(false) } @@ -610,50 +613,193 @@ context "when the MIN_QA_THRESHOLD is set to 10" do before do - stub_const("Claim::MIN_QA_THRESHOLD", 10) unless described_class::MIN_QA_THRESHOLD == 10 + stub_const("Policies::#{policy}::MIN_QA_THRESHOLD", 10) end context "with no previously approved claims" do + let!(:claims_for_other_policy) do + create_list( + :claim, + 1, + :approved, + :flagged_for_qa, + policy: other_policy, + academic_year: AcademicYear.current + ) + end it { is_expected.to eq(true) } end context "with 1 previously approved claim (1 flagged for QA)" do - let!(:claims_flagged_for_qa) { create_list(:claim, 1, :approved, :flagged_for_qa, academic_year: AcademicYear.current) } + let!(:claims_flagged_for_qa) do + create_list( + :claim, + 1, + :approved, + :flagged_for_qa, + policy: policy, + academic_year: AcademicYear.current + ) + end it { is_expected.to eq(false) } end context "with 2 previously approved claims (1 flagged for QA)" do - let!(:claims_flagged_for_qa) { create_list(:claim, 1, :approved, :flagged_for_qa, academic_year: AcademicYear.current) } - let!(:claims_not_flagged_for_qa) { create_list(:claim, 1, :approved, academic_year: AcademicYear.current) } + let!(:claims_flagged_for_qa) do + create_list( + :claim, + 1, + :approved, + :flagged_for_qa, + policy: policy, + academic_year: AcademicYear.current + ) + end + let!(:claims_not_flagged_for_qa) do + create_list( + :claim, + 1, + :approved, + policy: policy, + academic_year: AcademicYear.current + ) + end it { is_expected.to eq(false) } end context "with 9 previously approved claims (1 flagged for QA)" do - let!(:claims_flagged_for_qa) { create_list(:claim, 1, :approved, :flagged_for_qa, academic_year: AcademicYear.current) } - let!(:claims_not_flagged_for_qa) { create_list(:claim, 8, :approved, academic_year: AcademicYear.current) } + let!(:claims_flagged_for_qa) do + create_list( + :claim, + 1, + :approved, + :flagged_for_qa, + policy: policy, + academic_year: AcademicYear.current + ) + end + + let!(:claims_not_flagged_for_qa) do + create_list( + :claim, + 8, + :approved, + policy: policy, + academic_year: AcademicYear.current + ) + end + let!(:claims_for_other_policy) do + create_list( + :claim, + 1, + :approved, + :flagged_for_qa, + policy: other_policy, + academic_year: AcademicYear.current + ) + end it { is_expected.to eq(false) } end context "with 10 previously approved claims (1 flagged for QA)" do - let!(:claims_flagged_for_qa) { create_list(:claim, 1, :approved, :flagged_for_qa, academic_year: AcademicYear.current) } - let!(:claims_not_flagged_for_qa) { create_list(:claim, 9, :approved, academic_year: AcademicYear.current) } + let!(:claims_flagged_for_qa) do + create_list( + :claim, + 1, + :approved, + :flagged_for_qa, + policy: policy, + academic_year: AcademicYear.current + ) + end + let!(:claims_not_flagged_for_qa) do + create_list( + :claim, + 9, + :approved, + policy: policy, + academic_year: AcademicYear.current + ) + end + let!(:claims_for_other_policy) do + create_list( + :claim, + 1, + :approved, + :flagged_for_qa, + policy: other_policy, + academic_year: AcademicYear.current + ) + end it { is_expected.to eq(true) } end context "with 11 previously approved claims (2 flagged for QA)" do - let!(:claims_flagged_for_qa) { create_list(:claim, 2, :approved, :flagged_for_qa, academic_year: AcademicYear.current) } - let!(:claims_not_flagged_for_qa) { create_list(:claim, 10, :approved, academic_year: AcademicYear.current) } + let!(:claims_flagged_for_qa) do + create_list( + :claim, + 2, + :approved, + :flagged_for_qa, + policy: policy, + academic_year: AcademicYear.current + ) + end + let!(:claims_not_flagged_for_qa) do + create_list( + :claim, + 10, + :approved, + policy: policy, + academic_year: AcademicYear.current + ) + end + let!(:claims_for_other_policy) do + create_list( + :claim, + 2, + :approved, + policy: other_policy, + academic_year: AcademicYear.current + ) + end it { is_expected.to eq(false) } end context "with 21 previously approved claims (2 flagged for QA)" do - let!(:claims_flagged_for_qa) { create_list(:claim, 2, :approved, :flagged_for_qa, academic_year: AcademicYear.current) } - let!(:claims_not_flagged_for_qa) { create_list(:claim, 19, :approved, academic_year: AcademicYear.current) } + let!(:claims_flagged_for_qa) do + create_list( + :claim, + 2, + :approved, + :flagged_for_qa, + policy: policy, + academic_year: AcademicYear.current + ) + end + let!(:claims_not_flagged_for_qa) do + create_list( + :claim, + 19, + :approved, + policy: policy, + academic_year: AcademicYear.current + ) + end + let!(:claims_for_other_policy) do + create_list( + :claim, + 19, + :approved, + policy: other_policy, + academic_year: AcademicYear.current + ) + end it { is_expected.to eq(true) } end diff --git a/spec/support/stubbing_helpers.rb b/spec/support/stubbing_helpers.rb index 386e8b5be2..b0a9c68f44 100644 --- a/spec/support/stubbing_helpers.rb +++ b/spec/support/stubbing_helpers.rb @@ -1,6 +1,8 @@ module StubbingHelpers def disable_claim_qa_flagging - stub_const("Claim::MIN_QA_THRESHOLD", 0) + Policies::POLICIES.each do |policy| + stub_const("Policies::#{policy}::MIN_QA_THRESHOLD", 0) + end end def stub_otp_verification(otp_code: "123456", valid: true) From 1f53e01656b9af0f9d93f51d49139186819000be Mon Sep 17 00:00:00 2001 From: Richard Lynch Date: Mon, 1 Jul 2024 11:19:51 +0100 Subject: [PATCH 53/66] QA 100% of IRP claims A business requirement is for us to QA 100% of the claims for IRP --- app/models/policies/international_relocation_payments.rb | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/app/models/policies/international_relocation_payments.rb b/app/models/policies/international_relocation_payments.rb index e0acd520bb..b6d75d5aad 100644 --- a/app/models/policies/international_relocation_payments.rb +++ b/app/models/policies/international_relocation_payments.rb @@ -7,7 +7,7 @@ module InternationalRelocationPayments OTHER_CLAIMABLE_POLICIES = [] # Percentage of claims to QA - MIN_QA_THRESHOLD = 10 + MIN_QA_THRESHOLD = 100 # NOTE RL: currently IRP only has a single reply to address, so notify # doesn't show the address id From a5dc85778ec1ba27277842b74e4fa327f205774e Mon Sep 17 00:00:00 2001 From: Phil Lee Date: Thu, 27 Jun 2024 16:04:54 +0100 Subject: [PATCH 54/66] add teaching qualification form to FE journey --- .../teaching_qualification_form.rb | 39 ++++++++++++ .../journeys/further_education_payments.rb | 3 +- .../session_answers.rb | 1 + .../slug_sequence.rb | 2 +- .../claims/qualification.html.erb | 7 --- .../claims/teaching_qualification.html.erb | 17 ++++++ config/locales/en.yml | 5 ++ .../happy_js_path_spec.rb | 3 +- .../happy_path_spec.rb | 3 +- .../teaching_qualification_form_spec.rb | 59 +++++++++++++++++++ 10 files changed, 128 insertions(+), 11 deletions(-) create mode 100644 app/forms/journeys/further_education_payments/teaching_qualification_form.rb delete mode 100644 app/views/further_education_payments/claims/qualification.html.erb create mode 100644 app/views/further_education_payments/claims/teaching_qualification.html.erb create mode 100644 spec/forms/journeys/further_education_payments/teaching_qualification_form_spec.rb diff --git a/app/forms/journeys/further_education_payments/teaching_qualification_form.rb b/app/forms/journeys/further_education_payments/teaching_qualification_form.rb new file mode 100644 index 0000000000..a2b27a68c3 --- /dev/null +++ b/app/forms/journeys/further_education_payments/teaching_qualification_form.rb @@ -0,0 +1,39 @@ +module Journeys + module FurtherEducationPayments + class TeachingQualificationForm < Form + attribute :teaching_qualification, :string + + validates :teaching_qualification, + presence: {message: i18n_error_message(:inclusion)}, + inclusion: {in: ->(form) { form.radio_options.map(&:id) }, message: i18n_error_message(:inclusion)} + + def radio_options + [ + OpenStruct.new( + id: "yes", + name: "Yes" + ), + OpenStruct.new( + id: "not-yet", + name: "Not yet, I am currently enrolled on one and working towards completing it" + ), + OpenStruct.new( + id: "no-but-planned", + name: "No, but I plan to enrol on one in the next 12 months" + ), + OpenStruct.new( + id: "no-not-planned", + name: "No, and I do not plan to enrol on one in the next 12 months " + ) + ] + end + + def save + return false unless valid? + + journey_session.answers.assign_attributes(teaching_qualification:) + journey_session.save! + end + end + end +end diff --git a/app/models/journeys/further_education_payments.rb b/app/models/journeys/further_education_payments.rb index 1705beb167..f9e9e1444c 100644 --- a/app/models/journeys/further_education_payments.rb +++ b/app/models/journeys/further_education_payments.rb @@ -15,7 +15,8 @@ module FurtherEducationPayments "contract-type" => ContractTypeForm, "teaching-hours-per-week" => TeachingHoursPerWeekForm, "further-education-teaching-start-year" => FurtherEducationTeachingStartYearForm, - "subjects-taught" => SubjectsTaughtForm + "subjects-taught" => SubjectsTaughtForm, + "teaching-qualification" => TeachingQualificationForm } } end diff --git a/app/models/journeys/further_education_payments/session_answers.rb b/app/models/journeys/further_education_payments/session_answers.rb index 3921902e17..dec3430f93 100644 --- a/app/models/journeys/further_education_payments/session_answers.rb +++ b/app/models/journeys/further_education_payments/session_answers.rb @@ -8,6 +8,7 @@ class SessionAnswers < Journeys::SessionAnswers attribute :teaching_hours_per_week, :string attribute :further_education_teaching_start_year, :string attribute :subjects_taught, default: [] + attribute :teaching_qualification, :string def school @school ||= School.find(school_id) diff --git a/app/models/journeys/further_education_payments/slug_sequence.rb b/app/models/journeys/further_education_payments/slug_sequence.rb index 9565581810..eca2f510c9 100644 --- a/app/models/journeys/further_education_payments/slug_sequence.rb +++ b/app/models/journeys/further_education_payments/slug_sequence.rb @@ -12,7 +12,7 @@ class SlugSequence building-and-construction-courses teaching-courses half-teaching-hours - qualification + teaching-qualification poor-performance ] diff --git a/app/views/further_education_payments/claims/qualification.html.erb b/app/views/further_education_payments/claims/qualification.html.erb deleted file mode 100644 index fdad3e71f5..0000000000 --- a/app/views/further_education_payments/claims/qualification.html.erb +++ /dev/null @@ -1,7 +0,0 @@ -

- FE qualification goes here -

- -<%= form_with model: @form, url: claim_path(current_journey_routing_name), method: :patch, builder: GOVUKDesignSystemFormBuilder::FormBuilder, html: { novalidate: false } do |f| %> - <%= f.govuk_submit %> -<% end %> diff --git a/app/views/further_education_payments/claims/teaching_qualification.html.erb b/app/views/further_education_payments/claims/teaching_qualification.html.erb new file mode 100644 index 0000000000..bcbdcae16d --- /dev/null +++ b/app/views/further_education_payments/claims/teaching_qualification.html.erb @@ -0,0 +1,17 @@ +
+
+ <%= form_with model: @form, url: claim_path(current_journey_routing_name), method: :patch, builder: GOVUKDesignSystemFormBuilder::FormBuilder, html: { novalidate: false } do |f| %> + <%= f.govuk_error_summary %> + + <%= f.govuk_collection_radio_buttons :teaching_qualification, @form.radio_options, :id, :name, + legend: { + text: @form.t(:question), + tag: "h1", + size: "l" + }, + hint: { text: @form.t(:hint) } %> + + <%= f.govuk_submit %> + <% end %> +
+
diff --git a/config/locales/en.yml b/config/locales/en.yml index 3100758e5c..4a67ed96ca 100644 --- a/config/locales/en.yml +++ b/config/locales/en.yml @@ -813,6 +813,11 @@ en: hint: Select all that apply errors: inclusion: Select the subject areas you teach in or select you do not teach any of the listed subject areas + teaching_qualification: + question: Do you have a teaching qualification? + hint: Your response will be noted for future claims. If you don’t have a teaching qualification yet, make sure that you enrol on one or complete one in the next 12 months. + errors: + inclusion: Select whether you have, are currently enrolled or plan to enrol on a teaching qualification activerecord: errors: models: diff --git a/spec/features/further_education_payments/happy_js_path_spec.rb b/spec/features/further_education_payments/happy_js_path_spec.rb index 002d6b9856..9863de6557 100644 --- a/spec/features/further_education_payments/happy_js_path_spec.rb +++ b/spec/features/further_education_payments/happy_js_path_spec.rb @@ -51,7 +51,8 @@ expect(page).to have_content("FE half teaching hours goes here") click_button "Continue" - expect(page).to have_content("FE qualification goes here") + expect(page).to have_content("Do you have a teaching qualification?") + choose("Yes") click_button "Continue" expect(page).to have_content("FE poor performance goes here") diff --git a/spec/features/further_education_payments/happy_path_spec.rb b/spec/features/further_education_payments/happy_path_spec.rb index 75d2ae0e99..6e52ea9f4b 100644 --- a/spec/features/further_education_payments/happy_path_spec.rb +++ b/spec/features/further_education_payments/happy_path_spec.rb @@ -48,7 +48,8 @@ expect(page).to have_content("FE half teaching hours goes here") click_button "Continue" - expect(page).to have_content("FE qualification goes here") + expect(page).to have_content("Do you have a teaching qualification?") + choose("Yes") click_button "Continue" expect(page).to have_content("FE poor performance goes here") diff --git a/spec/forms/journeys/further_education_payments/teaching_qualification_form_spec.rb b/spec/forms/journeys/further_education_payments/teaching_qualification_form_spec.rb new file mode 100644 index 0000000000..1cb660aad5 --- /dev/null +++ b/spec/forms/journeys/further_education_payments/teaching_qualification_form_spec.rb @@ -0,0 +1,59 @@ +require "rails_helper" + +RSpec.describe Journeys::FurtherEducationPayments::TeachingQualificationForm, type: :model do + let(:journey) { Journeys::FurtherEducationPayments } + let(:journey_session) { create(:further_education_payments_session) } + let(:teaching_qualification) { nil } + + let(:params) do + ActionController::Parameters.new( + claim: { + teaching_qualification: + } + ) + end + + subject do + described_class.new( + journey_session:, + journey:, + params: + ) + end + + describe "validations" do + context "when no option selected" do + let(:teaching_qualification) { nil } + + it do + is_expected.not_to( + allow_value(nil) + .for(:teaching_qualification) + .with_message("Select whether you have, are currently enrolled or plan to enrol on a teaching qualification") + ) + end + end + + context "when non-existent injection option selected" do + let(:teaching_qualification) { "foo" } + + it do + is_expected.not_to( + allow_value("foo") + .for(:teaching_qualification) + .with_message("Select whether you have, are currently enrolled or plan to enrol on a teaching qualification") + ) + end + end + end + + describe "#save" do + let(:teaching_qualification) { "yes" } + + it "updates the journey session" do + expect { expect(subject.save).to be(true) }.to( + change { journey_session.reload.answers.teaching_qualification }.to("yes") + ) + end + end +end From 21d7e51e14fdc921914540c7bc74b31bf6e1d32d Mon Sep 17 00:00:00 2001 From: Phil Lee Date: Thu, 27 Jun 2024 17:45:40 +0100 Subject: [PATCH 55/66] add poor performance form to FE journey --- .../poor_performance_form.rb | 34 +++++++++++ .../journeys/further_education_payments.rb | 3 +- .../session_answers.rb | 2 + .../claims/poor_performance.html.erb | 34 +++++++++-- config/locales/en.yml | 14 +++++ .../happy_js_path_spec.rb | 9 ++- .../happy_path_spec.rb | 9 ++- .../poor_performance_form_spec.rb | 57 +++++++++++++++++++ 8 files changed, 153 insertions(+), 9 deletions(-) create mode 100644 app/forms/journeys/further_education_payments/poor_performance_form.rb create mode 100644 spec/forms/journeys/further_education_payments/poor_performance_form_spec.rb diff --git a/app/forms/journeys/further_education_payments/poor_performance_form.rb b/app/forms/journeys/further_education_payments/poor_performance_form.rb new file mode 100644 index 0000000000..15fb1c728f --- /dev/null +++ b/app/forms/journeys/further_education_payments/poor_performance_form.rb @@ -0,0 +1,34 @@ +module Journeys + module FurtherEducationPayments + class PoorPerformanceForm < Form + attribute :subject_to_formal_performance_action, :boolean + attribute :subject_to_disciplinary_action, :boolean + + validates :subject_to_formal_performance_action, inclusion: {in: [true, false], message: i18n_error_message("performance.inclusion")} + validates :subject_to_disciplinary_action, inclusion: {in: [true, false], message: i18n_error_message("disciplinary.inclusion")} + + def radio_options + [ + OpenStruct.new( + id: true, + name: "Yes" + ), + OpenStruct.new( + id: false, + name: "No" + ) + ] + end + + def save + return false if invalid? + + journey_session.answers.assign_attributes( + subject_to_formal_performance_action:, + subject_to_disciplinary_action: + ) + journey_session.save! + end + end + end +end diff --git a/app/models/journeys/further_education_payments.rb b/app/models/journeys/further_education_payments.rb index f9e9e1444c..85089e3acf 100644 --- a/app/models/journeys/further_education_payments.rb +++ b/app/models/journeys/further_education_payments.rb @@ -16,7 +16,8 @@ module FurtherEducationPayments "teaching-hours-per-week" => TeachingHoursPerWeekForm, "further-education-teaching-start-year" => FurtherEducationTeachingStartYearForm, "subjects-taught" => SubjectsTaughtForm, - "teaching-qualification" => TeachingQualificationForm + "teaching-qualification" => TeachingQualificationForm, + "poor-performance" => PoorPerformanceForm } } end diff --git a/app/models/journeys/further_education_payments/session_answers.rb b/app/models/journeys/further_education_payments/session_answers.rb index dec3430f93..3ef62aa669 100644 --- a/app/models/journeys/further_education_payments/session_answers.rb +++ b/app/models/journeys/further_education_payments/session_answers.rb @@ -9,6 +9,8 @@ class SessionAnswers < Journeys::SessionAnswers attribute :further_education_teaching_start_year, :string attribute :subjects_taught, default: [] attribute :teaching_qualification, :string + attribute :subject_to_formal_performance_action, :boolean + attribute :subject_to_disciplinary_action, :boolean def school @school ||= School.find(school_id) diff --git a/app/views/further_education_payments/claims/poor_performance.html.erb b/app/views/further_education_payments/claims/poor_performance.html.erb index f346f2a49f..48323259eb 100644 --- a/app/views/further_education_payments/claims/poor_performance.html.erb +++ b/app/views/further_education_payments/claims/poor_performance.html.erb @@ -1,7 +1,29 @@ -

- FE poor performance goes here -

+
+
+ <%= form_with model: @form, url: claim_path(current_journey_routing_name), method: :patch, builder: GOVUKDesignSystemFormBuilder::FormBuilder, html: { novalidate: false } do |f| %> + <%= f.govuk_error_summary %> -<%= form_with model: @form, url: claim_path(current_journey_routing_name), method: :patch, builder: GOVUKDesignSystemFormBuilder::FormBuilder, html: { novalidate: false } do |f| %> - <%= f.govuk_submit %> -<% end %> +

+ <%= @form.t(:heading) %> +

+ + <%= f.govuk_collection_radio_buttons :subject_to_formal_performance_action, @form.radio_options, :id, :name, + legend: { + text: @form.t("questions.performance.question"), + tag: "h2", + size: "m" + }, + hint: { text: @form.t("questions.performance.hint") } %> + + <%= f.govuk_collection_radio_buttons :subject_to_disciplinary_action, @form.radio_options, :id, :name, + legend: { + text: @form.t("questions.disciplinary.question"), + tag: "h2", + size: "m" + }, + hint: { text: @form.t("questions.disciplinary.hint") } %> + + <%= f.govuk_submit %> + <% end %> +
+
diff --git a/config/locales/en.yml b/config/locales/en.yml index 4a67ed96ca..ed69839402 100644 --- a/config/locales/en.yml +++ b/config/locales/en.yml @@ -818,6 +818,20 @@ en: hint: Your response will be noted for future claims. If you don’t have a teaching qualification yet, make sure that you enrol on one or complete one in the next 12 months. errors: inclusion: Select whether you have, are currently enrolled or plan to enrol on a teaching qualification + poor_performance: + heading: Tell us if you are currently under any performance measures or disciplinary action + questions: + performance: + question: Have any performance measures been started against you? + hint: This will be as a result of your underperformance as a teacher over a period of time. It could put your employment at the further education (FE) provider at risk and is something we may check with them as it will affect your eligibility. + disciplinary: + question: Are you currently subject to disciplinary action? + hint: This is more serious than performance measures and could be because of misconduct. It is something we may check with your FE provider as it will affect your eligibility. + errors: + performance: + inclusion: Select yes if you are subject to formal action for poor performance at work + disciplinary: + inclusion: Select yes if you are subject to disciplinary action activerecord: errors: models: diff --git a/spec/features/further_education_payments/happy_js_path_spec.rb b/spec/features/further_education_payments/happy_js_path_spec.rb index 9863de6557..65760be790 100644 --- a/spec/features/further_education_payments/happy_js_path_spec.rb +++ b/spec/features/further_education_payments/happy_js_path_spec.rb @@ -55,7 +55,14 @@ choose("Yes") click_button "Continue" - expect(page).to have_content("FE poor performance goes here") + expect(page).to have_content("Have any performance measures been started against you?") + within all(".govuk-fieldset")[0] do + choose("No") + end + expect(page).to have_content("Are you currently subject to disciplinary action?") + within all(".govuk-fieldset")[1] do + choose("No") + end click_button "Continue" expect(page).to have_content("FE check your answers goes here") diff --git a/spec/features/further_education_payments/happy_path_spec.rb b/spec/features/further_education_payments/happy_path_spec.rb index 6e52ea9f4b..4379d34daf 100644 --- a/spec/features/further_education_payments/happy_path_spec.rb +++ b/spec/features/further_education_payments/happy_path_spec.rb @@ -52,7 +52,14 @@ choose("Yes") click_button "Continue" - expect(page).to have_content("FE poor performance goes here") + expect(page).to have_content("Have any performance measures been started against you?") + within all(".govuk-fieldset")[0] do + choose("No") + end + expect(page).to have_content("Are you currently subject to disciplinary action?") + within all(".govuk-fieldset")[1] do + choose("No") + end click_button "Continue" expect(page).to have_content("FE check your answers goes here") diff --git a/spec/forms/journeys/further_education_payments/poor_performance_form_spec.rb b/spec/forms/journeys/further_education_payments/poor_performance_form_spec.rb new file mode 100644 index 0000000000..ceb4014739 --- /dev/null +++ b/spec/forms/journeys/further_education_payments/poor_performance_form_spec.rb @@ -0,0 +1,57 @@ +require "rails_helper" + +RSpec.describe Journeys::FurtherEducationPayments::PoorPerformanceForm, type: :model do + let(:journey) { Journeys::FurtherEducationPayments } + let(:journey_session) { create(:further_education_payments_session) } + let(:subject_to_formal_performance_action) { nil } + let(:subject_to_disciplinary_action) { nil } + + let(:params) do + ActionController::Parameters.new( + claim: { + subject_to_formal_performance_action:, + subject_to_disciplinary_action: + } + ) + end + + subject do + described_class.new( + journey_session:, + journey:, + params: + ) + end + + describe "validations" do + context "when no options selected" do + it do + is_expected.not_to( + allow_value(nil) + .for(:subject_to_formal_performance_action) + .with_message("Select yes if you are subject to formal action for poor performance at work") + ) + end + + it do + is_expected.not_to( + allow_value(nil) + .for(:subject_to_disciplinary_action) + .with_message("Select yes if you are subject to disciplinary action") + ) + end + end + end + + describe "#save" do + let(:subject_to_formal_performance_action) { "true" } + let(:subject_to_disciplinary_action) { "false" } + + it "updates the journey session" do + expect { expect(subject.save).to be(true) }.to( + change { journey_session.reload.answers.subject_to_formal_performance_action }.to(true) + .and(change { journey_session.reload.answers.subject_to_disciplinary_action }.to(false)) + ) + end + end +end From 1c12a17fc98bc94b6481b545c1e92da7250feee5 Mon Sep 17 00:00:00 2001 From: Phil Lee Date: Mon, 1 Jul 2024 15:46:37 +0100 Subject: [PATCH 56/66] refactor poor performance - a single poor performance form that is now shared between journeys - refactored to use GOVUK formbuilder --- .../poor_performance_form.rb | 21 ---- .../poor_performance_form.rb | 34 ------ app/forms/poor_performance_form.rb | 39 +++++++ .../answers_presenter.rb | 4 +- .../claims/poor_performance.html.erb | 102 ++++-------------- config/locales/en.yml | 28 ++--- spec/features/backlink_spec.rb | 8 +- ...er_claim_journey_dependent_answers_spec.rb | 12 ++- .../combined_teacher_claim_journey_spec.rb | 24 +++-- ...ourney_with_teacher_id_check_email_spec.rb | 14 ++- ...urney_with_teacher_id_check_mobile_spec.rb | 8 +- ...cher_claim_journey_with_teacher_id_spec.rb | 10 +- ...eer_payments_claim_lupp_ineligible_spec.rb | 20 ++-- .../early_career_payments_claim_spec.rb | 52 +++++---- spec/features/hmrc_bank_validation_spec.rb | 8 +- spec/features/ineligibility_reason_spec.rb | 32 ++++-- ...gible_early_career_payments_claims_spec.rb | 74 ++++++++----- ...ible_levelling_up_premium_payments_spec.rb | 14 ++- spec/features/itt_subject_selection_spec.rb | 12 ++- .../levelling_up_premium_payments_spec.rb | 12 ++- .../poor_performance_form_spec.rb | 57 ---------- .../poor_performance_form_spec.rb | 6 +- 22 files changed, 277 insertions(+), 314 deletions(-) delete mode 100644 app/forms/journeys/additional_payments_for_teaching/poor_performance_form.rb delete mode 100644 app/forms/journeys/further_education_payments/poor_performance_form.rb create mode 100644 app/forms/poor_performance_form.rb delete mode 100644 spec/forms/journeys/further_education_payments/poor_performance_form_spec.rb rename spec/forms/{journeys/additional_payments_for_teaching => }/poor_performance_form_spec.rb (90%) diff --git a/app/forms/journeys/additional_payments_for_teaching/poor_performance_form.rb b/app/forms/journeys/additional_payments_for_teaching/poor_performance_form.rb deleted file mode 100644 index 715d10548b..0000000000 --- a/app/forms/journeys/additional_payments_for_teaching/poor_performance_form.rb +++ /dev/null @@ -1,21 +0,0 @@ -module Journeys - module AdditionalPaymentsForTeaching - class PoorPerformanceForm < Form - attribute :subject_to_formal_performance_action, :boolean - attribute :subject_to_disciplinary_action, :boolean - - validates :subject_to_formal_performance_action, inclusion: {in: [true, false], message: i18n_error_message("subject_to_formal_performance_action.inclusion")} - validates :subject_to_disciplinary_action, inclusion: {in: [true, false], message: i18n_error_message("subject_to_disciplinary_action.inclusion")} - - def save - return false unless valid? - - journey_session.answers.assign_attributes( - subject_to_formal_performance_action:, - subject_to_disciplinary_action: - ) - journey_session.save - end - end - end -end diff --git a/app/forms/journeys/further_education_payments/poor_performance_form.rb b/app/forms/journeys/further_education_payments/poor_performance_form.rb deleted file mode 100644 index 15fb1c728f..0000000000 --- a/app/forms/journeys/further_education_payments/poor_performance_form.rb +++ /dev/null @@ -1,34 +0,0 @@ -module Journeys - module FurtherEducationPayments - class PoorPerformanceForm < Form - attribute :subject_to_formal_performance_action, :boolean - attribute :subject_to_disciplinary_action, :boolean - - validates :subject_to_formal_performance_action, inclusion: {in: [true, false], message: i18n_error_message("performance.inclusion")} - validates :subject_to_disciplinary_action, inclusion: {in: [true, false], message: i18n_error_message("disciplinary.inclusion")} - - def radio_options - [ - OpenStruct.new( - id: true, - name: "Yes" - ), - OpenStruct.new( - id: false, - name: "No" - ) - ] - end - - def save - return false if invalid? - - journey_session.answers.assign_attributes( - subject_to_formal_performance_action:, - subject_to_disciplinary_action: - ) - journey_session.save! - end - end - end -end diff --git a/app/forms/poor_performance_form.rb b/app/forms/poor_performance_form.rb new file mode 100644 index 0000000000..0fe1032b07 --- /dev/null +++ b/app/forms/poor_performance_form.rb @@ -0,0 +1,39 @@ +class PoorPerformanceForm < Form + attribute :subject_to_formal_performance_action, :boolean + attribute :subject_to_disciplinary_action, :boolean + + validates :subject_to_formal_performance_action, + inclusion: { + in: [true, false], + message: i18n_error_message("performance.inclusion") + } + + validates :subject_to_disciplinary_action, + inclusion: { + in: [true, false], + message: i18n_error_message("disciplinary.inclusion") + } + + def radio_options + [ + OpenStruct.new( + id: true, + name: "Yes" + ), + OpenStruct.new( + id: false, + name: "No" + ) + ] + end + + def save + return false if invalid? + + journey_session.answers.assign_attributes( + subject_to_formal_performance_action:, + subject_to_disciplinary_action: + ) + journey_session.save + end +end diff --git a/app/models/journeys/additional_payments_for_teaching/answers_presenter.rb b/app/models/journeys/additional_payments_for_teaching/answers_presenter.rb index 4c3376a047..3e38d921f1 100644 --- a/app/models/journeys/additional_payments_for_teaching/answers_presenter.rb +++ b/app/models/journeys/additional_payments_for_teaching/answers_presenter.rb @@ -90,7 +90,7 @@ def employed_directly def subject_to_formal_performance_action [ - t("additional_payments.forms.poor_performance.questions.formal_performance_action"), + t("additional_payments.forms.poor_performance.questions.performance.question"), (journey_session.answers.subject_to_formal_performance_action? ? "Yes" : "No"), "poor-performance" ] @@ -98,7 +98,7 @@ def subject_to_formal_performance_action def subject_to_disciplinary_action [ - t("additional_payments.forms.poor_performance.questions.disciplinary_action"), + t("additional_payments.forms.poor_performance.questions.disciplinary.question"), (journey_session.answers.subject_to_disciplinary_action? ? "Yes" : "No"), "poor-performance" ] diff --git a/app/views/additional_payments/claims/poor_performance.html.erb b/app/views/additional_payments/claims/poor_performance.html.erb index 07206acecd..6ce9afc512 100644 --- a/app/views/additional_payments/claims/poor_performance.html.erb +++ b/app/views/additional_payments/claims/poor_performance.html.erb @@ -1,89 +1,31 @@ -<% content_for(:page_title, page_title(t("#{@form.i18n_namespace}.forms.poor_performance.questions.poor_performance"), journey: current_journey_routing_name, show_error: @form.errors.any?)) %> +<% content_for(:page_title, page_title(@form.t(:heading), journey: current_journey_routing_name, show_error: @form.errors.any?)) %>
- <%= render("shared/error_summary", instance: @form, errored_field_id_overrides: { - "subject_to_formal_performance_action": "claim_subject_to_formal_performance_action_true", - "subject_to_disciplinary_action": "claim_subject_to_disciplinary_action_true" - }) if @form.errors.any? %> - <%= form_for @form, url: claim_path(current_journey_routing_name) do |form| %> + <%= form_for @form, url: claim_path(current_journey_routing_name), builder: GOVUKDesignSystemFormBuilder::FormBuilder do |f| %> + <%= f.govuk_error_summary %> +

- <%= t("#{@form.i18n_namespace}.forms.poor_performance.questions.poor_performance") %> + <%= @form.t(:heading) %>

- <%= form_group_tag @form, :subject_to_formal_performance_action do %> - - <%= form.hidden_field :subject_to_formal_performance_action %> - -
- - -

- <%= t("#{@form.i18n_namespace}.forms.poor_performance.questions.formal_performance_action") %> -

-
- - <%= errors_tag @form, :subject_to_formal_performance_action %> - -
- <%= t("#{@form.i18n_namespace}.forms.poor_performance.questions.formal_performance_action_hint") %> -
- -
- -
- <%= form.radio_button(:subject_to_formal_performance_action, true, class: "govuk-radios__input") %> - <%= form.label :subject_to_formal_performance_action_true, "Yes", class: "govuk-label govuk-radios__label" %> -
- -
- <%= form.radio_button(:subject_to_formal_performance_action, false, class: "govuk-radios__input") %> - <%= form.label :subject_to_formal_performance_action_false, "No", class: "govuk-label govuk-radios__label" %> -
- -
- -
- - <% end %> - - <%= form_group_tag @form, :subject_to_disciplinary_action do %> - - <%= form.hidden_field :subject_to_disciplinary_action %> - -
- - -

- <%= t("#{@form.i18n_namespace}.forms.poor_performance.questions.disciplinary_action") %> -

-
- - <%= errors_tag @form, :subject_to_disciplinary_action %> - -
- <%= t("#{@form.i18n_namespace}.forms.poor_performance.questions.disciplinary_action_hint") %> -
- -
- -
- <%= form.radio_button(:subject_to_disciplinary_action, true, class: "govuk-radios__input") %> - <%= form.label :subject_to_disciplinary_action_true, "Yes", class: "govuk-label govuk-radios__label" %> -
- -
- <%= form.radio_button(:subject_to_disciplinary_action, false, class: "govuk-radios__input") %> - <%= form.label :subject_to_disciplinary_action_false, "No", class: "govuk-label govuk-radios__label" %> -
- -
- -
- - <% end %> - - <%= form.submit "Continue", class: "govuk-button", data: {module: "govuk-button"} %> + <%= f.govuk_collection_radio_buttons :subject_to_formal_performance_action, @form.radio_options, :id, :name, + legend: { + text: @form.t("questions.performance.question"), + tag: "h2", + size: "m" + }, + hint: { text: @form.t("questions.performance.hint") } %> + + <%= f.govuk_collection_radio_buttons :subject_to_disciplinary_action, @form.radio_options, :id, :name, + legend: { + text: @form.t("questions.disciplinary.question"), + tag: "h2", + size: "m" + }, + hint: { text: @form.t("questions.disciplinary.hint") } %> + + <%= f.govuk_submit %> <% end %>
diff --git a/config/locales/en.yml b/config/locales/en.yml index ed69839402..1f6b38a59f 100644 --- a/config/locales/en.yml +++ b/config/locales/en.yml @@ -486,21 +486,23 @@ en: errors: blank: "Select yes if you have completed your induction" poor_performance: + heading: Tell us if you are currently under any performance measures or disciplinary action questions: - poor_performance: Tell us if you are currently under any performance measures or disciplinary action - disciplinary_action: "Are you currently subject to disciplinary action?" - disciplinary_action_hint: - "This is more serious than performance measures and could be because of misconduct. It is something we may - check with your school as it will affect your eligibility." - formal_performance_action: "Have any performance measures been started against you?" - formal_performance_action_hint: - "This will be as a result of your underperformance as a teacher over a period of time. It could put your - employment at the school at risk and is something we may check with your school as it will affect your - eligibility." - errors: - subject_to_formal_performance_action: + performance: + question: "Have any performance measures been started against you?" + hint: + "This will be as a result of your underperformance as a teacher over a period of time. It could put your + employment at the school at risk and is something we may check with your school as it will affect your + eligibility." + disciplinary: + question: "Are you currently subject to disciplinary action?" + hint: + "This is more serious than performance measures and could be because of misconduct. It is something we may + check with your school as it will affect your eligibility." + errors: + performance: inclusion: Select yes if you are subject to formal action for poor performance at work - subject_to_disciplinary_action: + disciplinary: inclusion: Select yes if you are subject to disciplinary action qualification: questions: diff --git a/spec/features/backlink_spec.rb b/spec/features/backlink_spec.rb index 49dde0d14a..c63f82c992 100644 --- a/spec/features/backlink_spec.rb +++ b/spec/features/backlink_spec.rb @@ -24,8 +24,12 @@ click_on "Continue" expect(page).to have_content("Tell us if you are currently under any performance measures or disciplinary action") - choose "claim_subject_to_formal_performance_action_false" - choose "claim_subject_to_disciplinary_action_false" + within all(".govuk-fieldset")[0] do + choose("No") + end + within all(".govuk-fieldset")[1] do + choose("No") + end click_on "Continue" expect(page).to have_content("Which route into teaching did you take?") diff --git a/spec/features/combined_teacher_claim_journey_dependent_answers_spec.rb b/spec/features/combined_teacher_claim_journey_dependent_answers_spec.rb index 8eae020b23..47f964046e 100644 --- a/spec/features/combined_teacher_claim_journey_dependent_answers_spec.rb +++ b/spec/features/combined_teacher_claim_journey_dependent_answers_spec.rb @@ -32,10 +32,14 @@ click_on "Continue" # - Poor performance - expect(page).to have_text(I18n.t("additional_payments.forms.poor_performance.questions.formal_performance_action")) - expect(page).to have_text(I18n.t("additional_payments.forms.poor_performance.questions.disciplinary_action")) - choose "claim_subject_to_formal_performance_action_false" - choose "claim_subject_to_disciplinary_action_false" + expect(page).to have_text(I18n.t("additional_payments.forms.poor_performance.questions.performance.question")) + expect(page).to have_text(I18n.t("additional_payments.forms.poor_performance.questions.disciplinary.question")) + within all(".govuk-fieldset")[0] do + choose("No") + end + within all(".govuk-fieldset")[1] do + choose("No") + end click_on "Continue" # - What route into teaching did you take? diff --git a/spec/features/combined_teacher_claim_journey_spec.rb b/spec/features/combined_teacher_claim_journey_spec.rb index 148bdcbc5e..2d8e2a7bcf 100644 --- a/spec/features/combined_teacher_claim_journey_spec.rb +++ b/spec/features/combined_teacher_claim_journey_spec.rb @@ -59,11 +59,15 @@ click_on "Continue" # - Poor performance - expect(page).to have_text(I18n.t("additional_payments.forms.poor_performance.questions.formal_performance_action")) - expect(page).to have_text(I18n.t("additional_payments.forms.poor_performance.questions.disciplinary_action")) + expect(page).to have_text(I18n.t("additional_payments.forms.poor_performance.questions.performance.question")) + expect(page).to have_text(I18n.t("additional_payments.forms.poor_performance.questions.disciplinary.question")) - choose "claim_subject_to_formal_performance_action_false" - choose "claim_subject_to_disciplinary_action_false" + within all(".govuk-fieldset")[0] do + choose("No") + end + within all(".govuk-fieldset")[1] do + choose("No") + end click_on "Continue" # - What route into teaching did you take? @@ -278,11 +282,15 @@ click_on "Continue" # - Poor performance - expect(page).to have_text(I18n.t("additional_payments.forms.poor_performance.questions.formal_performance_action")) - expect(page).to have_text(I18n.t("additional_payments.forms.poor_performance.questions.disciplinary_action")) + expect(page).to have_text(I18n.t("additional_payments.forms.poor_performance.questions.performance.question")) + expect(page).to have_text(I18n.t("additional_payments.forms.poor_performance.questions.disciplinary.question")) - choose "claim_subject_to_formal_performance_action_false" - choose "claim_subject_to_disciplinary_action_false" + within all(".govuk-fieldset")[0] do + choose("No") + end + within all(".govuk-fieldset")[1] do + choose("No") + end click_on "Continue" # - What route into teaching did you take? diff --git a/spec/features/combined_teacher_claim_journey_with_teacher_id_check_email_spec.rb b/spec/features/combined_teacher_claim_journey_with_teacher_id_check_email_spec.rb index 117da10bcc..733201f095 100644 --- a/spec/features/combined_teacher_claim_journey_with_teacher_id_check_email_spec.rb +++ b/spec/features/combined_teacher_claim_journey_with_teacher_id_check_email_spec.rb @@ -102,11 +102,15 @@ def navigate_to_check_email_page(school:) click_on "Continue" # - Poor performance - expect(page).to have_text(I18n.t("additional_payments.forms.poor_performance.questions.formal_performance_action")) - expect(page).to have_text(I18n.t("additional_payments.forms.poor_performance.questions.disciplinary_action")) - - choose "claim_subject_to_formal_performance_action_false" - choose "claim_subject_to_disciplinary_action_false" + expect(page).to have_text(I18n.t("additional_payments.forms.poor_performance.questions.performance.question")) + expect(page).to have_text(I18n.t("additional_payments.forms.poor_performance.questions.disciplinary.question")) + + within all(".govuk-fieldset")[0] do + choose("No") + end + within all(".govuk-fieldset")[1] do + choose("No") + end click_on "Continue" # - What route into teaching did you take? diff --git a/spec/features/combined_teacher_claim_journey_with_teacher_id_check_mobile_spec.rb b/spec/features/combined_teacher_claim_journey_with_teacher_id_check_mobile_spec.rb index c69f5553d2..2e27ea0f0a 100644 --- a/spec/features/combined_teacher_claim_journey_with_teacher_id_check_mobile_spec.rb +++ b/spec/features/combined_teacher_claim_journey_with_teacher_id_check_mobile_spec.rb @@ -132,8 +132,12 @@ def navigate_to_check_mobile_page click_on "Continue" # - Performance Issues - choose "claim_subject_to_formal_performance_action_false" - choose "claim_subject_to_disciplinary_action_false" + within all(".govuk-fieldset")[0] do + choose("No") + end + within all(".govuk-fieldset")[1] do + choose("No") + end click_on "Continue" # - Check and confirm qualifications diff --git a/spec/features/combined_teacher_claim_journey_with_teacher_id_spec.rb b/spec/features/combined_teacher_claim_journey_with_teacher_id_spec.rb index a851a8289c..e2f5708dfa 100644 --- a/spec/features/combined_teacher_claim_journey_with_teacher_id_spec.rb +++ b/spec/features/combined_teacher_claim_journey_with_teacher_id_spec.rb @@ -362,10 +362,14 @@ def navigate_until_performance_related_questions(expect_induction_question: fals click_on "Continue" # - Performance Issues - expect(page).to have_text(I18n.t("additional_payments.forms.poor_performance.questions.poor_performance")) + expect(page).to have_text(I18n.t("additional_payments.forms.poor_performance.heading")) - choose "claim_subject_to_formal_performance_action_false" - choose "claim_subject_to_disciplinary_action_false" + within all(".govuk-fieldset")[0] do + choose("No") + end + within all(".govuk-fieldset")[1] do + choose("No") + end click_on "Continue" end end diff --git a/spec/features/early_career_payments_claim_lupp_ineligible_spec.rb b/spec/features/early_career_payments_claim_lupp_ineligible_spec.rb index 9dc04b804f..e0361c4700 100644 --- a/spec/features/early_career_payments_claim_lupp_ineligible_spec.rb +++ b/spec/features/early_career_payments_claim_lupp_ineligible_spec.rb @@ -45,18 +45,20 @@ click_on "Continue" # - Performance Issues - expect(page).to have_text(I18n.t("additional_payments.forms.poor_performance.questions.poor_performance")) - expect(page).to have_text(I18n.t("additional_payments.forms.poor_performance.questions.formal_performance_action")) - expect(page).to have_text(I18n.t("additional_payments.forms.poor_performance.questions.formal_performance_action_hint")) + expect(page).to have_text(I18n.t("additional_payments.forms.poor_performance.heading")) + expect(page).to have_text(I18n.t("additional_payments.forms.poor_performance.questions.performance.question")) + expect(page).to have_text(I18n.t("additional_payments.forms.poor_performance.questions.performance.hint")) - # No - choose "claim_subject_to_formal_performance_action_false" + within all(".govuk-fieldset")[0] do + choose("No") + end - expect(page).to have_text(I18n.t("additional_payments.forms.poor_performance.questions.disciplinary_action")) - expect(page).to have_text(I18n.t("additional_payments.forms.poor_performance.questions.disciplinary_action_hint")) + expect(page).to have_text(I18n.t("additional_payments.forms.poor_performance.questions.disciplinary.question")) + expect(page).to have_text(I18n.t("additional_payments.forms.poor_performance.questions.disciplinary.hint")) - # "No" - choose "claim_subject_to_disciplinary_action_false" + within all(".govuk-fieldset")[1] do + choose("No") + end click_on "Continue" diff --git a/spec/features/early_career_payments_claim_spec.rb b/spec/features/early_career_payments_claim_spec.rb index 75d65d87b5..485f96495c 100644 --- a/spec/features/early_career_payments_claim_spec.rb +++ b/spec/features/early_career_payments_claim_spec.rb @@ -46,18 +46,20 @@ click_on "Continue" # - Performance Issues - expect(page).to have_text(I18n.t("additional_payments.forms.poor_performance.questions.poor_performance")) - expect(page).to have_text(I18n.t("additional_payments.forms.poor_performance.questions.formal_performance_action")) - expect(page).to have_text(I18n.t("additional_payments.forms.poor_performance.questions.formal_performance_action_hint")) + expect(page).to have_text(I18n.t("additional_payments.forms.poor_performance.heading")) + expect(page).to have_text(I18n.t("additional_payments.forms.poor_performance.questions.performance.question")) + expect(page).to have_text(I18n.t("additional_payments.forms.poor_performance.questions.performance.hint")) - # No - choose "claim_subject_to_formal_performance_action_false" + within all(".govuk-fieldset")[0] do + choose("No") + end - expect(page).to have_text(I18n.t("additional_payments.forms.poor_performance.questions.disciplinary_action")) - expect(page).to have_text(I18n.t("additional_payments.forms.poor_performance.questions.disciplinary_action_hint")) + expect(page).to have_text(I18n.t("additional_payments.forms.poor_performance.questions.disciplinary.question")) + expect(page).to have_text(I18n.t("additional_payments.forms.poor_performance.questions.disciplinary.hint")) - # "No" - choose "claim_subject_to_disciplinary_action_false" + within all(".govuk-fieldset")[1] do + choose("No") + end click_on "Continue" @@ -320,7 +322,7 @@ expect(journey_session.reload.answers.employed_directly).to eql true # - Are you currently subject to action for poor performance - expect(page).to have_text(I18n.t("additional_payments.forms.poor_performance.questions.formal_performance_action")) + expect(page).to have_text(I18n.t("additional_payments.forms.poor_performance.questions.performance.question")) end context "Route into teaching" do @@ -464,18 +466,20 @@ click_on "Continue" # - Performance Issues - expect(page).to have_text(I18n.t("additional_payments.forms.poor_performance.questions.poor_performance")) - expect(page).to have_text(I18n.t("additional_payments.forms.poor_performance.questions.formal_performance_action")) - expect(page).to have_text(I18n.t("additional_payments.forms.poor_performance.questions.formal_performance_action_hint")) + expect(page).to have_text(I18n.t("additional_payments.forms.poor_performance.heading")) + expect(page).to have_text(I18n.t("additional_payments.forms.poor_performance.questions.performance.question")) + expect(page).to have_text(I18n.t("additional_payments.forms.poor_performance.questions.performance.hint")) - # No - choose "claim_subject_to_formal_performance_action_false" + within all(".govuk-fieldset")[0] do + choose("No") + end - expect(page).to have_text(I18n.t("additional_payments.forms.poor_performance.questions.disciplinary_action")) - expect(page).to have_text(I18n.t("additional_payments.forms.poor_performance.questions.disciplinary_action_hint")) + expect(page).to have_text(I18n.t("additional_payments.forms.poor_performance.questions.disciplinary.question")) + expect(page).to have_text(I18n.t("additional_payments.forms.poor_performance.questions.disciplinary.hint")) - # "No" - choose "claim_subject_to_disciplinary_action_false" + within all(".govuk-fieldset")[1] do + choose("No") + end click_on "Continue" # - What route into teaching did you take? @@ -1008,10 +1012,12 @@ click_on "Continue" # - Performance Issues - # No - choose "claim_subject_to_formal_performance_action_false" - # "No" - choose "claim_subject_to_disciplinary_action_false" + within all(".govuk-fieldset")[0] do + choose("No") + end + within all(".govuk-fieldset")[1] do + choose("No") + end click_on "Continue" # - What route into teaching did you take? diff --git a/spec/features/hmrc_bank_validation_spec.rb b/spec/features/hmrc_bank_validation_spec.rb index 13ae1f7bbd..64d3f354b1 100644 --- a/spec/features/hmrc_bank_validation_spec.rb +++ b/spec/features/hmrc_bank_validation_spec.rb @@ -34,8 +34,12 @@ def get_to_bank_details_page click_on "Continue" # - Poor performance - choose "claim_subject_to_formal_performance_action_false" - choose "claim_subject_to_disciplinary_action_false" + within all(".govuk-fieldset")[0] do + choose("No") + end + within all(".govuk-fieldset")[1] do + choose("No") + end click_on "Continue" # - What route into teaching did you take? diff --git a/spec/features/ineligibility_reason_spec.rb b/spec/features/ineligibility_reason_spec.rb index 958e4019b6..53cddade6e 100644 --- a/spec/features/ineligibility_reason_spec.rb +++ b/spec/features/ineligibility_reason_spec.rb @@ -39,24 +39,36 @@ end scenario "formal performance action" do - choose "claim_subject_to_formal_performance_action_true" - choose "claim_subject_to_disciplinary_action_false" + within all(".govuk-fieldset")[0] do + choose("Yes") + end + within all(".govuk-fieldset")[1] do + choose("No") + end click_on "Continue" expect(page).to have_css("div#generic") end scenario "disciplinary action" do - choose "claim_subject_to_formal_performance_action_false" - choose "claim_subject_to_disciplinary_action_true" + within all(".govuk-fieldset")[0] do + choose("No") + end + within all(".govuk-fieldset")[1] do + choose("Yes") + end click_on "Continue" expect(page).to have_css("div#generic") end scenario "formal performance and disciplinary action" do - choose "claim_subject_to_formal_performance_action_true" - choose "claim_subject_to_disciplinary_action_true" + within all(".govuk-fieldset")[0] do + choose("Yes") + end + within all(".govuk-fieldset")[1] do + choose("Yes") + end click_on "Continue" expect(page).to have_css("div#generic") @@ -305,8 +317,12 @@ def navigate_to_year_selection(school) click_on "Continue" # - Poor performance - choose "claim_subject_to_formal_performance_action_false" - choose "claim_subject_to_disciplinary_action_false" + within all(".govuk-fieldset")[0] do + choose("No") + end + within all(".govuk-fieldset")[1] do + choose("No") + end click_on "Continue" # - What route into teaching did you take? diff --git a/spec/features/ineligible_early_career_payments_claims_spec.rb b/spec/features/ineligible_early_career_payments_claims_spec.rb index 67b558c0de..11bec92a48 100644 --- a/spec/features/ineligible_early_career_payments_claims_spec.rb +++ b/spec/features/ineligible_early_career_payments_claims_spec.rb @@ -70,11 +70,15 @@ click_on "Continue" # - Poor performance - expect(page).to have_text(I18n.t("additional_payments.forms.poor_performance.questions.formal_performance_action")) - expect(page).to have_text(I18n.t("additional_payments.forms.poor_performance.questions.disciplinary_action")) + expect(page).to have_text(I18n.t("additional_payments.forms.poor_performance.questions.performance.question")) + expect(page).to have_text(I18n.t("additional_payments.forms.poor_performance.questions.disciplinary.question")) - choose "claim_subject_to_formal_performance_action_true" - choose "claim_subject_to_disciplinary_action_false" + within all(".govuk-fieldset")[0] do + choose("Yes") + end + within all(".govuk-fieldset")[1] do + choose("No") + end click_on "Continue" expect(page).to have_text(I18n.t("additional_payments.ineligible.heading")) @@ -110,11 +114,15 @@ click_on "Continue" # - Poor performance - expect(page).to have_text(I18n.t("additional_payments.forms.poor_performance.questions.formal_performance_action")) - expect(page).to have_text(I18n.t("additional_payments.forms.poor_performance.questions.disciplinary_action")) + expect(page).to have_text(I18n.t("additional_payments.forms.poor_performance.questions.performance.question")) + expect(page).to have_text(I18n.t("additional_payments.forms.poor_performance.questions.disciplinary.question")) - choose "claim_subject_to_formal_performance_action_false" - choose "claim_subject_to_disciplinary_action_true" + within all(".govuk-fieldset")[0] do + choose("No") + end + within all(".govuk-fieldset")[1] do + choose("Yes") + end click_on "Continue" expect(page).to have_text(I18n.t("additional_payments.ineligible.heading")) @@ -150,11 +158,15 @@ click_on "Continue" # - Poor performance - expect(page).to have_text(I18n.t("additional_payments.forms.poor_performance.questions.formal_performance_action")) - expect(page).to have_text(I18n.t("additional_payments.forms.poor_performance.questions.disciplinary_action")) + expect(page).to have_text(I18n.t("additional_payments.forms.poor_performance.questions.performance.question")) + expect(page).to have_text(I18n.t("additional_payments.forms.poor_performance.questions.disciplinary.question")) - choose "claim_subject_to_formal_performance_action_true" - choose "claim_subject_to_disciplinary_action_true" + within all(".govuk-fieldset")[0] do + choose("Yes") + end + within all(".govuk-fieldset")[1] do + choose("Yes") + end click_on "Continue" expect(page).to have_text(I18n.t("additional_payments.ineligible.heading")) @@ -276,11 +288,15 @@ click_on "Continue" # - Poor performance - expect(page).to have_text(I18n.t("additional_payments.forms.poor_performance.questions.formal_performance_action")) - expect(page).to have_text(I18n.t("additional_payments.forms.poor_performance.questions.disciplinary_action")) + expect(page).to have_text(I18n.t("additional_payments.forms.poor_performance.questions.performance.question")) + expect(page).to have_text(I18n.t("additional_payments.forms.poor_performance.questions.disciplinary.question")) - choose "claim_subject_to_formal_performance_action_false" - choose "claim_subject_to_disciplinary_action_false" + within all(".govuk-fieldset")[0] do + choose("No") + end + within all(".govuk-fieldset")[1] do + choose("No") + end click_on "Continue" # - What route into teaching did you take? @@ -341,11 +357,15 @@ click_on "Continue" # - Poor performance - expect(page).to have_text(I18n.t("additional_payments.forms.poor_performance.questions.formal_performance_action")) - expect(page).to have_text(I18n.t("additional_payments.forms.poor_performance.questions.disciplinary_action")) + expect(page).to have_text(I18n.t("additional_payments.forms.poor_performance.questions.performance.question")) + expect(page).to have_text(I18n.t("additional_payments.forms.poor_performance.questions.disciplinary.question")) - choose "claim_subject_to_formal_performance_action_false" - choose "claim_subject_to_disciplinary_action_false" + within all(".govuk-fieldset")[0] do + choose("No") + end + within all(".govuk-fieldset")[1] do + choose("No") + end click_on "Continue" # - What route into teaching did you take? @@ -413,11 +433,15 @@ click_on "Continue" # - Poor performance - expect(page).to have_text(I18n.t("additional_payments.forms.poor_performance.questions.formal_performance_action")) - expect(page).to have_text(I18n.t("additional_payments.forms.poor_performance.questions.disciplinary_action")) - - choose "claim_subject_to_formal_performance_action_false" - choose "claim_subject_to_disciplinary_action_false" + expect(page).to have_text(I18n.t("additional_payments.forms.poor_performance.questions.performance.question")) + expect(page).to have_text(I18n.t("additional_payments.forms.poor_performance.questions.disciplinary.question")) + + within all(".govuk-fieldset")[0] do + choose("No") + end + within all(".govuk-fieldset")[1] do + choose("No") + end click_on "Continue" # - What route into teaching did you take? diff --git a/spec/features/ineligible_levelling_up_premium_payments_spec.rb b/spec/features/ineligible_levelling_up_premium_payments_spec.rb index 6893a25f60..8f19bbe515 100644 --- a/spec/features/ineligible_levelling_up_premium_payments_spec.rb +++ b/spec/features/ineligible_levelling_up_premium_payments_spec.rb @@ -77,11 +77,15 @@ click_on "Continue" # - Poor performance - expect(page).to have_text(I18n.t("additional_payments.forms.poor_performance.questions.formal_performance_action")) - expect(page).to have_text(I18n.t("additional_payments.forms.poor_performance.questions.disciplinary_action")) - - choose "claim_subject_to_formal_performance_action_false" - choose "claim_subject_to_disciplinary_action_false" + expect(page).to have_text(I18n.t("additional_payments.forms.poor_performance.questions.performance.question")) + expect(page).to have_text(I18n.t("additional_payments.forms.poor_performance.questions.disciplinary.question")) + + within all(".govuk-fieldset")[0] do + choose("No") + end + within all(".govuk-fieldset")[1] do + choose("No") + end click_on "Continue" # - What route into teaching did you take? diff --git a/spec/features/itt_subject_selection_spec.rb b/spec/features/itt_subject_selection_spec.rb index 72f57f1bac..d507d699e4 100644 --- a/spec/features/itt_subject_selection_spec.rb +++ b/spec/features/itt_subject_selection_spec.rb @@ -206,11 +206,15 @@ def navigate_to_year_selection(school) click_on "Continue" # - Poor performance - expect(page).to have_text(I18n.t("additional_payments.forms.poor_performance.questions.formal_performance_action")) - expect(page).to have_text(I18n.t("additional_payments.forms.poor_performance.questions.disciplinary_action")) + expect(page).to have_text(I18n.t("additional_payments.forms.poor_performance.questions.performance.question")) + expect(page).to have_text(I18n.t("additional_payments.forms.poor_performance.questions.disciplinary.question")) - choose "claim_subject_to_formal_performance_action_false" - choose "claim_subject_to_disciplinary_action_false" + within all(".govuk-fieldset")[0] do + choose("No") + end + within all(".govuk-fieldset")[1] do + choose("No") + end click_on "Continue" # - What route into teaching did you take? diff --git a/spec/features/levelling_up_premium_payments_spec.rb b/spec/features/levelling_up_premium_payments_spec.rb index 9e716ec98f..ffb7232a1d 100644 --- a/spec/features/levelling_up_premium_payments_spec.rb +++ b/spec/features/levelling_up_premium_payments_spec.rb @@ -63,11 +63,15 @@ def check_eligibility_up_to_itt_subject click_on "Continue" # - Poor performance - expect(page).to have_text(I18n.t("additional_payments.forms.poor_performance.questions.formal_performance_action")) - expect(page).to have_text(I18n.t("additional_payments.forms.poor_performance.questions.disciplinary_action")) + expect(page).to have_text(I18n.t("additional_payments.forms.poor_performance.questions.performance.question")) + expect(page).to have_text(I18n.t("additional_payments.forms.poor_performance.questions.disciplinary.question")) - choose "claim_subject_to_formal_performance_action_false" - choose "claim_subject_to_disciplinary_action_false" + within all(".govuk-fieldset")[0] do + choose("No") + end + within all(".govuk-fieldset")[1] do + choose("No") + end click_on "Continue" # - What route into teaching did you take? diff --git a/spec/forms/journeys/further_education_payments/poor_performance_form_spec.rb b/spec/forms/journeys/further_education_payments/poor_performance_form_spec.rb deleted file mode 100644 index ceb4014739..0000000000 --- a/spec/forms/journeys/further_education_payments/poor_performance_form_spec.rb +++ /dev/null @@ -1,57 +0,0 @@ -require "rails_helper" - -RSpec.describe Journeys::FurtherEducationPayments::PoorPerformanceForm, type: :model do - let(:journey) { Journeys::FurtherEducationPayments } - let(:journey_session) { create(:further_education_payments_session) } - let(:subject_to_formal_performance_action) { nil } - let(:subject_to_disciplinary_action) { nil } - - let(:params) do - ActionController::Parameters.new( - claim: { - subject_to_formal_performance_action:, - subject_to_disciplinary_action: - } - ) - end - - subject do - described_class.new( - journey_session:, - journey:, - params: - ) - end - - describe "validations" do - context "when no options selected" do - it do - is_expected.not_to( - allow_value(nil) - .for(:subject_to_formal_performance_action) - .with_message("Select yes if you are subject to formal action for poor performance at work") - ) - end - - it do - is_expected.not_to( - allow_value(nil) - .for(:subject_to_disciplinary_action) - .with_message("Select yes if you are subject to disciplinary action") - ) - end - end - end - - describe "#save" do - let(:subject_to_formal_performance_action) { "true" } - let(:subject_to_disciplinary_action) { "false" } - - it "updates the journey session" do - expect { expect(subject.save).to be(true) }.to( - change { journey_session.reload.answers.subject_to_formal_performance_action }.to(true) - .and(change { journey_session.reload.answers.subject_to_disciplinary_action }.to(false)) - ) - end - end -end diff --git a/spec/forms/journeys/additional_payments_for_teaching/poor_performance_form_spec.rb b/spec/forms/poor_performance_form_spec.rb similarity index 90% rename from spec/forms/journeys/additional_payments_for_teaching/poor_performance_form_spec.rb rename to spec/forms/poor_performance_form_spec.rb index 810f0cf84d..d4cf89040b 100644 --- a/spec/forms/journeys/additional_payments_for_teaching/poor_performance_form_spec.rb +++ b/spec/forms/poor_performance_form_spec.rb @@ -1,6 +1,6 @@ require "rails_helper" -RSpec.describe Journeys::AdditionalPaymentsForTeaching::PoorPerformanceForm do +RSpec.describe PoorPerformanceForm do subject(:form) { described_class.new(journey_session:, journey:, params:) } let(:journey) { Journeys::AdditionalPaymentsForTeaching } @@ -26,7 +26,7 @@ expect(form).to be_invalid expect(form.errors[:subject_to_formal_performance_action]) - .to eq([form.i18n_errors_path("subject_to_formal_performance_action.inclusion")]) + .to eq([form.i18n_errors_path("performance.inclusion")]) end it "can be true or false" do @@ -44,7 +44,7 @@ expect(form).to be_invalid expect(form.errors[:subject_to_disciplinary_action]) - .to eq([form.i18n_errors_path("subject_to_disciplinary_action.inclusion")]) + .to eq([form.i18n_errors_path("disciplinary.inclusion")]) end it "can be true or false" do From ccddd652128b1e7b1f9702bef4ca65d4e55523c2 Mon Sep 17 00:00:00 2001 From: Phil Lee Date: Fri, 28 Jun 2024 16:44:01 +0100 Subject: [PATCH 57/66] FE journey handle ineligible as lack teaching --- .../ineligible_form.rb | 9 ++++++++ .../journeys/further_education_payments.rb | 5 ++-- .../eligibility_checker.rb | 3 --- .../policy_eligibility_checker.rb | 10 +++++++- ...le_lack_teaching_responsibilities.html.erb | 19 +++++++++++++++ .../claims/ineligible.html.erb | 2 +- .../ineligible_paths_spec.rb | 22 ++++++++++++++++++ .../policy_eligibility_checker_spec.rb | 23 +++++++++++++++++++ 8 files changed, 86 insertions(+), 7 deletions(-) create mode 100644 app/forms/journeys/further_education_payments/ineligible_form.rb create mode 100644 app/views/further_education_payments/claims/_ineligible_lack_teaching_responsibilities.html.erb create mode 100644 spec/features/further_education_payments/ineligible_paths_spec.rb create mode 100644 spec/models/policies/further_education_payments/policy_eligibility_checker_spec.rb diff --git a/app/forms/journeys/further_education_payments/ineligible_form.rb b/app/forms/journeys/further_education_payments/ineligible_form.rb new file mode 100644 index 0000000000..f5ad3333da --- /dev/null +++ b/app/forms/journeys/further_education_payments/ineligible_form.rb @@ -0,0 +1,9 @@ +module Journeys + module FurtherEducationPayments + class IneligibleForm < Form + def journey_eligibility_checker + @journey_eligibility_checker ||= EligibilityChecker.new(journey_session:) + end + end + end +end diff --git a/app/models/journeys/further_education_payments.rb b/app/models/journeys/further_education_payments.rb index 85089e3acf..6e6351c3a2 100644 --- a/app/models/journeys/further_education_payments.rb +++ b/app/models/journeys/further_education_payments.rb @@ -6,7 +6,7 @@ module FurtherEducationPayments ROUTING_NAME = "further-education-payments" VIEW_PATH = "further_education_payments" I18N_NAMESPACE = "further_education_payments" - POLICIES = [] + POLICIES = [Policies::FurtherEducationPayments] FORMS = { "claims" => { "teaching-responsibilities" => TeachingResponsibilitiesForm, @@ -17,7 +17,8 @@ module FurtherEducationPayments "further-education-teaching-start-year" => FurtherEducationTeachingStartYearForm, "subjects-taught" => SubjectsTaughtForm, "teaching-qualification" => TeachingQualificationForm, - "poor-performance" => PoorPerformanceForm + "poor-performance" => PoorPerformanceForm, + "ineligible" => IneligibleForm } } end diff --git a/app/models/journeys/further_education_payments/eligibility_checker.rb b/app/models/journeys/further_education_payments/eligibility_checker.rb index d30c874ca0..534e017321 100644 --- a/app/models/journeys/further_education_payments/eligibility_checker.rb +++ b/app/models/journeys/further_education_payments/eligibility_checker.rb @@ -1,9 +1,6 @@ module Journeys module FurtherEducationPayments class EligibilityChecker < Journeys::EligibilityChecker - def ineligible? - false - end end end end diff --git a/app/models/policies/further_education_payments/policy_eligibility_checker.rb b/app/models/policies/further_education_payments/policy_eligibility_checker.rb index 08f9abb3e7..b9fd1b46a1 100644 --- a/app/models/policies/further_education_payments/policy_eligibility_checker.rb +++ b/app/models/policies/further_education_payments/policy_eligibility_checker.rb @@ -10,11 +10,19 @@ def initialize(answers:) end def status + return :ineligible if ineligible? + :eligible_now end def ineligible? - false + ineligibility_reason.present? + end + + def ineligibility_reason + if answers.teaching_responsibilities == false + :lack_teaching_responsibilities + end end end end diff --git a/app/views/further_education_payments/claims/_ineligible_lack_teaching_responsibilities.html.erb b/app/views/further_education_payments/claims/_ineligible_lack_teaching_responsibilities.html.erb new file mode 100644 index 0000000000..e22255f18a --- /dev/null +++ b/app/views/further_education_payments/claims/_ineligible_lack_teaching_responsibilities.html.erb @@ -0,0 +1,19 @@ +
+
+

+ You are not eligible +

+ +

+ In order to claim a levelling up premium payment, you must be employed as a member of staff with teaching responsibilities. +

+ +

+ For more information, check the eligibility criteria for <%= govuk_link_to "levelling up premium payments for early career further education teachers", "https://www.gov.uk/guidance/levelling-up-premium-payments-for-fe-teachers", new_tab: true %>. +

+ +

+ The information entered is not stored. If you are unsure your information is correct, <%= govuk_link_to "start again", claim_path(current_journey_routing_name, "claim") %>. +

+
+
diff --git a/app/views/further_education_payments/claims/ineligible.html.erb b/app/views/further_education_payments/claims/ineligible.html.erb index 438136931e..d95a12b23f 100644 --- a/app/views/further_education_payments/claims/ineligible.html.erb +++ b/app/views/further_education_payments/claims/ineligible.html.erb @@ -1 +1 @@ -FE ineligible goes here +<%= render "ineligible_#{@form.journey_eligibility_checker.ineligibility_reason}" %> diff --git a/spec/features/further_education_payments/ineligible_paths_spec.rb b/spec/features/further_education_payments/ineligible_paths_spec.rb new file mode 100644 index 0000000000..833894e426 --- /dev/null +++ b/spec/features/further_education_payments/ineligible_paths_spec.rb @@ -0,0 +1,22 @@ +require "rails_helper" + +RSpec.feature "Further education payments ineligible paths" do + scenario "when no teaching responsibilities" do + when_further_education_payments_journey_configuration_exists + + visit landing_page_path(Journeys::FurtherEducationPayments::ROUTING_NAME) + expect(page).to have_link("Start now") + click_link "Start now" + + expect(page).to have_content("Are you a member of staff with teaching responsibilities?") + choose "No" + click_button "Continue" + + expect(page).to have_content("You are not eligible") + expect(page).to have_content("you must be employed as a member of staff with teaching responsibilities") + end + + def when_further_education_payments_journey_configuration_exists + create(:journey_configuration, :further_education_payments) + end +end diff --git a/spec/models/policies/further_education_payments/policy_eligibility_checker_spec.rb b/spec/models/policies/further_education_payments/policy_eligibility_checker_spec.rb new file mode 100644 index 0000000000..d7c9d52da9 --- /dev/null +++ b/spec/models/policies/further_education_payments/policy_eligibility_checker_spec.rb @@ -0,0 +1,23 @@ +require "rails_helper" + +describe Policies::FurtherEducationPayments::PolicyEligibilityChecker do + let(:answers) do + build(:further_education_payments_answers) + end + + subject { described_class.new(answers: answers) } + + describe "#status, #ineligible?, #ineligibility_reason" do + context "when ineligible as lacking teaching responsibility" do + let(:answers) do + build(:further_education_payments_answers, teaching_responsibilities: false) + end + + it "is ineligble as :lack_teaching_responsibilities" do + expect(subject).to be_ineligible + expect(subject.status).to eql(:ineligible) + expect(subject.ineligibility_reason).to eql(:lack_teaching_responsibilities) + end + end + end +end From aaf644e81ae2eac16ecb13fcdb8835106bd5c119 Mon Sep 17 00:00:00 2001 From: Phil Lee Date: Mon, 1 Jul 2024 11:41:57 +0100 Subject: [PATCH 58/66] add eligible page to FE journey --- .../check_your_answers_form.rb | 9 +++++++ .../eligible_form.rb | 9 +++++++ .../journeys/further_education_payments.rb | 1 + .../slug_sequence.rb | 1 + .../claims/check_your_answers.html.erb | 4 +++ .../claims/eligible.html.erb | 26 +++++++++++++++++++ .../happy_js_path_spec.rb | 4 +++ .../happy_path_spec.rb | 4 +++ 8 files changed, 58 insertions(+) create mode 100644 app/forms/journeys/further_education_payments/check_your_answers_form.rb create mode 100644 app/forms/journeys/further_education_payments/eligible_form.rb create mode 100644 app/views/further_education_payments/claims/eligible.html.erb diff --git a/app/forms/journeys/further_education_payments/check_your_answers_form.rb b/app/forms/journeys/further_education_payments/check_your_answers_form.rb new file mode 100644 index 0000000000..ead9c4a800 --- /dev/null +++ b/app/forms/journeys/further_education_payments/check_your_answers_form.rb @@ -0,0 +1,9 @@ +module Journeys + module FurtherEducationPayments + class CheckYourAnswersForm < Form + def save + true + end + end + end +end diff --git a/app/forms/journeys/further_education_payments/eligible_form.rb b/app/forms/journeys/further_education_payments/eligible_form.rb new file mode 100644 index 0000000000..c1cebb5e1b --- /dev/null +++ b/app/forms/journeys/further_education_payments/eligible_form.rb @@ -0,0 +1,9 @@ +module Journeys + module FurtherEducationPayments + class EligibleForm < Form + def save + true + end + end + end +end diff --git a/app/models/journeys/further_education_payments.rb b/app/models/journeys/further_education_payments.rb index 6e6351c3a2..0a417d8184 100644 --- a/app/models/journeys/further_education_payments.rb +++ b/app/models/journeys/further_education_payments.rb @@ -18,6 +18,7 @@ module FurtherEducationPayments "subjects-taught" => SubjectsTaughtForm, "teaching-qualification" => TeachingQualificationForm, "poor-performance" => PoorPerformanceForm, + "check-your-answers" => CheckYourAnswersForm, "ineligible" => IneligibleForm } } diff --git a/app/models/journeys/further_education_payments/slug_sequence.rb b/app/models/journeys/further_education_payments/slug_sequence.rb index eca2f510c9..e55a8f29df 100644 --- a/app/models/journeys/further_education_payments/slug_sequence.rb +++ b/app/models/journeys/further_education_payments/slug_sequence.rb @@ -18,6 +18,7 @@ class SlugSequence RESULTS_SLUGS = %w[ check-your-answers + eligible ineligible ].freeze diff --git a/app/views/further_education_payments/claims/check_your_answers.html.erb b/app/views/further_education_payments/claims/check_your_answers.html.erb index 533f8cb82e..4cfef0b5be 100644 --- a/app/views/further_education_payments/claims/check_your_answers.html.erb +++ b/app/views/further_education_payments/claims/check_your_answers.html.erb @@ -1,3 +1,7 @@

FE check your answers goes here

+ +<%= form_with model: @form, url: claim_path(current_journey_routing_name), method: :patch, builder: GOVUKDesignSystemFormBuilder::FormBuilder, html: { novalidate: false } do |f| %> + <%= f.govuk_submit %> +<% end %> diff --git a/app/views/further_education_payments/claims/eligible.html.erb b/app/views/further_education_payments/claims/eligible.html.erb new file mode 100644 index 0000000000..9a1a8936d9 --- /dev/null +++ b/app/views/further_education_payments/claims/eligible.html.erb @@ -0,0 +1,26 @@ +
+
+ <%= form_with model: @form, url: claim_path(current_journey_routing_name), method: :patch, builder: GOVUKDesignSystemFormBuilder::FormBuilder, html: { novalidate: false } do |f| %> + <%= govuk_panel( + title_text: "You’re eligible for a financial incentive payment", + html_attributes: { + class: "govuk-panel--informational" + } + ) %> + +
+ Based on what you’ve told us, you can apply for an early career further education financial incentive payment of: +
+ +
+ £??? +
+ +
+ For more information about why you are eligible, read about the <%= govuk_link_to "levelling up premium payments for early career further education teachers", "https://www.gov.uk/guidance/levelling-up-premium-payments-for-fe-teachers", new_tab: true %>. +
+ + <%= f.govuk_submit "Apply now" %> + <% end %> +
+
diff --git a/spec/features/further_education_payments/happy_js_path_spec.rb b/spec/features/further_education_payments/happy_js_path_spec.rb index 65760be790..31f3c45586 100644 --- a/spec/features/further_education_payments/happy_js_path_spec.rb +++ b/spec/features/further_education_payments/happy_js_path_spec.rb @@ -66,6 +66,10 @@ click_button "Continue" expect(page).to have_content("FE check your answers goes here") + click_button "Continue" + + expect(page).to have_content("You’re eligible for a financial incentive payment") + expect(page).to have_content("Apply now") end def when_further_education_payments_journey_configuration_exists diff --git a/spec/features/further_education_payments/happy_path_spec.rb b/spec/features/further_education_payments/happy_path_spec.rb index 4379d34daf..66d673dbe8 100644 --- a/spec/features/further_education_payments/happy_path_spec.rb +++ b/spec/features/further_education_payments/happy_path_spec.rb @@ -63,6 +63,10 @@ click_button "Continue" expect(page).to have_content("FE check your answers goes here") + click_button "Continue" + + expect(page).to have_content("You’re eligible for a financial incentive payment") + expect(page).to have_content("Apply now") end def when_further_education_payments_journey_configuration_exists From b9e55dbd683d445ed0ff227249753bd605635180 Mon Sep 17 00:00:00 2001 From: Felix Clack Date: Mon, 1 Jul 2024 09:12:09 +0100 Subject: [PATCH 59/66] Add a visa check task for IRP For the international relocation payments journey we want to add a new admin task for checking the visa type provided. We collect the visa type as part of the journey, so we want an admin task to confirm this. --- app/models/claim_checking_tasks.rb | 3 ++- .../admin_tasks_presenter.rb | 6 +++++ app/models/task.rb | 1 + app/views/admin/tasks/visa.html.erb | 26 +++++++++++++++++++ config/locales/en.yml | 3 +++ ...dmin_view_claim_feature_shared_examples.rb | 2 +- 6 files changed, 39 insertions(+), 2 deletions(-) create mode 100644 app/views/admin/tasks/visa.html.erb diff --git a/app/models/claim_checking_tasks.rb b/app/models/claim_checking_tasks.rb index e00040e4dc..f1725845fa 100644 --- a/app/models/claim_checking_tasks.rb +++ b/app/models/claim_checking_tasks.rb @@ -12,7 +12,7 @@ def initialize(claim) delegate :policy, to: :claim def applicable_task_names - return ["identity_confirmation"] if policy.international_relocation_payments? + return ["identity_confirmation", "visa"] if policy.international_relocation_payments? @applicable_task_names ||= Task::NAMES.dup.tap do |task_names| task_names.delete("induction_confirmation") unless claim.policy == Policies::EarlyCareerPayments @@ -21,6 +21,7 @@ def applicable_task_names task_names.delete("payroll_details") unless claim.must_manually_validate_bank_details? task_names.delete("matching_details") unless matching_claims.exists? task_names.delete("payroll_gender") unless claim.payroll_gender_missing? || task_names_for_claim.include?("payroll_gender") + task_names.delete("visa") unless claim.policy.international_relocation_payments? end end diff --git a/app/models/policies/international_relocation_payments/admin_tasks_presenter.rb b/app/models/policies/international_relocation_payments/admin_tasks_presenter.rb index e64aa294ea..9e7f35fddd 100644 --- a/app/models/policies/international_relocation_payments/admin_tasks_presenter.rb +++ b/app/models/policies/international_relocation_payments/admin_tasks_presenter.rb @@ -16,6 +16,12 @@ def identity_confirmation ] end + def visa + [ + ["Visa type", eligibility.visa_type] + ] + end + private delegate :eligibility, to: :claim diff --git a/app/models/task.rb b/app/models/task.rb index 8dae76bdab..b2d48af068 100644 --- a/app/models/task.rb +++ b/app/models/task.rb @@ -18,6 +18,7 @@ class Task < ApplicationRecord payroll_details matching_details payroll_gender + visa ].freeze belongs_to :claim diff --git a/app/views/admin/tasks/visa.html.erb b/app/views/admin/tasks/visa.html.erb new file mode 100644 index 0000000000..3110ab6a7d --- /dev/null +++ b/app/views/admin/tasks/visa.html.erb @@ -0,0 +1,26 @@ +<% content_for(:page_title) { page_title("Claim #{@claim.reference} visa check for #{@claim.policy.short_name}") } %> +<%= link_to "Back", admin_claim_tasks_path(claim_id: @claim.id), class: "govuk-back-link" %> +<%= render "shared/error_summary", instance: @task, errored_field_id_overrides: { "passed": "task_passed_true" } if @task.errors.any? %> + +
+ <%= render "claim_summary", claim: @claim, heading: "Visa check" %> + +
+

<%= @current_task_name.humanize %>

+
+ +
+ <%= render "admin/claims/answers", answers: @tasks_presenter.visa %> +
+ +
+ <% if !@task.passed.nil? %> + <%= render "task_outcome", task: @task %> + <% else %> + <%= render "form", task_name: "visa", claim: @claim %> + <% end %> + + <%= render partial: "admin/task_pagination" %> +
+
+ diff --git a/config/locales/en.yml b/config/locales/en.yml index 1f6b38a59f..d989bfee03 100644 --- a/config/locales/en.yml +++ b/config/locales/en.yml @@ -153,6 +153,7 @@ en: student_loan_plan: "Check student loan plan" payroll_details: "Check bank/building society account details" census_subjects_taught: "Check eligible subjects are taught" + visa: "Check visa" undo_decision: approved: "Undo approval" rejected: "Undo rejection" @@ -780,6 +781,8 @@ en: task_questions: identity_confirmation: title: "Did %{claim_full_name} submit the claim?" + visa: + title: "Is the claimant’s visa type eligible for a claim?" further_education_payments: landing_page: Find out if you are eligible for any incentive payments for further education teachers diff --git a/spec/support/admin_view_claim_feature_shared_examples.rb b/spec/support/admin_view_claim_feature_shared_examples.rb index 939e59cbcc..60616d168c 100644 --- a/spec/support/admin_view_claim_feature_shared_examples.rb +++ b/spec/support/admin_view_claim_feature_shared_examples.rb @@ -179,7 +179,7 @@ def expect_page_to_have_policy_sections(policy) when Policies::EarlyCareerPayments ["Identity confirmation", "Qualifications", "Induction confirmation", "Census subjects taught", "Employment", "Student loan plan", "Decision"] when Policies::InternationalRelocationPayments - ["Identity confirmation", "Decision"] + ["Identity confirmation", "Visa", "Decision"] else raise "Unimplemented policy: #{policy}" end From 7326aeb51c5651db660bdadae0ddbb10cd060ab5 Mon Sep 17 00:00:00 2001 From: Colin Saliceti Date: Mon, 1 Jul 2024 16:37:55 +0100 Subject: [PATCH 60/66] DNS configuration for test and production domains --- .../config/production.tfvars.json | 17 +++++++++++++++++ .../config/production_Terrafile | 3 +++ .../config/test.tfvars.json | 16 ++++++++++++++++ .../environment_domains/config/test_Terrafile | 3 +++ terraform/domains/environment_domains/main.tf | 12 ++++++++++++ .../domains/environment_domains/terraform.tf | 19 +++++++++++++++++++ .../domains/environment_domains/variables.tf | 4 ++++ 7 files changed, 74 insertions(+) create mode 100644 terraform/domains/environment_domains/config/production.tfvars.json create mode 100644 terraform/domains/environment_domains/config/production_Terrafile create mode 100644 terraform/domains/environment_domains/config/test.tfvars.json create mode 100644 terraform/domains/environment_domains/config/test_Terrafile create mode 100644 terraform/domains/environment_domains/main.tf create mode 100644 terraform/domains/environment_domains/terraform.tf create mode 100644 terraform/domains/environment_domains/variables.tf diff --git a/terraform/domains/environment_domains/config/production.tfvars.json b/terraform/domains/environment_domains/config/production.tfvars.json new file mode 100644 index 0000000000..523c65e21e --- /dev/null +++ b/terraform/domains/environment_domains/config/production.tfvars.json @@ -0,0 +1,17 @@ +{ + "hosted_zone": { + "claim-additional-teaching-payment.service.gov.uk": { + "front_door_name": "s189p01-capt-dom-fd", + "resource_group_name": "s189p01-capt-dom-rg", + "domains": [ + "apex", + "www" + ], + "cached_paths": [ + "/assets/*" + ], + "environment_short": "pd", + "origin_hostname": "s118p01-app-as.azurewebsites.net" + } + } +} diff --git a/terraform/domains/environment_domains/config/production_Terrafile b/terraform/domains/environment_domains/config/production_Terrafile new file mode 100644 index 0000000000..58e60b3c88 --- /dev/null +++ b/terraform/domains/environment_domains/config/production_Terrafile @@ -0,0 +1,3 @@ +domains: + source: "https://github.com/DFE-Digital/terraform-modules" + version: "stable" diff --git a/terraform/domains/environment_domains/config/test.tfvars.json b/terraform/domains/environment_domains/config/test.tfvars.json new file mode 100644 index 0000000000..80327c3c91 --- /dev/null +++ b/terraform/domains/environment_domains/config/test.tfvars.json @@ -0,0 +1,16 @@ +{ + "hosted_zone": { + "claim-additional-teaching-payment.service.gov.uk": { + "front_door_name": "s189p01-capt-dom-fd", + "resource_group_name": "s189p01-capt-dom-rg", + "domains": [ + "test" + ], + "cached_paths": [ + "/assets/*" + ], + "environment_short": "ts", + "origin_hostname": "s118t01-app-as.azurewebsites.net" + } + } +} diff --git a/terraform/domains/environment_domains/config/test_Terrafile b/terraform/domains/environment_domains/config/test_Terrafile new file mode 100644 index 0000000000..dfce270ef6 --- /dev/null +++ b/terraform/domains/environment_domains/config/test_Terrafile @@ -0,0 +1,3 @@ +domains: + source: "https://github.com/DFE-Digital/terraform-modules" + version: "testing" diff --git a/terraform/domains/environment_domains/main.tf b/terraform/domains/environment_domains/main.tf new file mode 100644 index 0000000000..50aacc8386 --- /dev/null +++ b/terraform/domains/environment_domains/main.tf @@ -0,0 +1,12 @@ +# Used to create domains to be managed by front door. +module "domains" { + for_each = var.hosted_zone + source = "./vendor/modules/domains//domains/environment_domains" + zone = each.key + front_door_name = each.value.front_door_name + resource_group_name = each.value.resource_group_name + domains = each.value.domains + environment = each.value.environment_short + host_name = each.value.origin_hostname + cached_paths = try(each.value.cached_paths, []) +} diff --git a/terraform/domains/environment_domains/terraform.tf b/terraform/domains/environment_domains/terraform.tf new file mode 100644 index 0000000000..a322044fe9 --- /dev/null +++ b/terraform/domains/environment_domains/terraform.tf @@ -0,0 +1,19 @@ +terraform { + + required_version = "= 1.8.4" + required_providers { + azurerm = { + source = "hashicorp/azurerm" + version = "3.104.2" + } + } + backend "azurerm" { + container_name = "terraform-state" + } +} + +provider "azurerm" { + features {} + + skip_provider_registration = true +} diff --git a/terraform/domains/environment_domains/variables.tf b/terraform/domains/environment_domains/variables.tf new file mode 100644 index 0000000000..ad63e546fd --- /dev/null +++ b/terraform/domains/environment_domains/variables.tf @@ -0,0 +1,4 @@ +variable "hosted_zone" { + type = map(any) + default = {} +} From c39aa1b07922c6271d902df69357126763839f2f Mon Sep 17 00:00:00 2001 From: Colin Saliceti Date: Tue, 2 Jul 2024 11:54:26 +0100 Subject: [PATCH 61/66] Redirect apex to www canonical domain The redirect is set up using front door instead of the ruby code --- .../environment_domains/config/production.tfvars.json | 6 +++++- terraform/domains/environment_domains/main.tf | 1 + 2 files changed, 6 insertions(+), 1 deletion(-) diff --git a/terraform/domains/environment_domains/config/production.tfvars.json b/terraform/domains/environment_domains/config/production.tfvars.json index 523c65e21e..b752b31c6d 100644 --- a/terraform/domains/environment_domains/config/production.tfvars.json +++ b/terraform/domains/environment_domains/config/production.tfvars.json @@ -11,7 +11,11 @@ "/assets/*" ], "environment_short": "pd", - "origin_hostname": "s118p01-app-as.azurewebsites.net" + "origin_hostname": "s118p01-app-as.azurewebsites.net", + "redirect_rules": [{ + "from-domain": "apex", + "to-domain": "www.claim-additional-teaching-payment.service.gov.uk" + }] } } } diff --git a/terraform/domains/environment_domains/main.tf b/terraform/domains/environment_domains/main.tf index 50aacc8386..c1409765d8 100644 --- a/terraform/domains/environment_domains/main.tf +++ b/terraform/domains/environment_domains/main.tf @@ -9,4 +9,5 @@ module "domains" { environment = each.value.environment_short host_name = each.value.origin_hostname cached_paths = try(each.value.cached_paths, []) + redirect_rules = try(each.value.redirect_rules, null) } From c37f7e701a89448b81a1b7913f5944957d18259c Mon Sep 17 00:00:00 2001 From: Felix Clack Date: Tue, 2 Jul 2024 09:59:26 +0100 Subject: [PATCH 62/66] Add a task for checking arrival date We want to confirm the date of entry provided is eligible for an IRP claim. --- app/models/claim_checking_tasks.rb | 3 ++- .../admin_tasks_presenter.rb | 6 +++++ app/models/task.rb | 1 + app/views/admin/tasks/arrival_date.html.erb | 25 +++++++++++++++++++ config/initializers/date_formats.rb | 1 + config/locales/en.yml | 4 +++ .../eligibilities.rb | 5 ++++ ...dmin_view_claim_feature_shared_examples.rb | 2 +- 8 files changed, 45 insertions(+), 2 deletions(-) create mode 100644 app/views/admin/tasks/arrival_date.html.erb diff --git a/app/models/claim_checking_tasks.rb b/app/models/claim_checking_tasks.rb index f1725845fa..6cce65f32a 100644 --- a/app/models/claim_checking_tasks.rb +++ b/app/models/claim_checking_tasks.rb @@ -12,7 +12,7 @@ def initialize(claim) delegate :policy, to: :claim def applicable_task_names - return ["identity_confirmation", "visa"] if policy.international_relocation_payments? + return %w[identity_confirmation visa arrival_date] if policy.international_relocation_payments? @applicable_task_names ||= Task::NAMES.dup.tap do |task_names| task_names.delete("induction_confirmation") unless claim.policy == Policies::EarlyCareerPayments @@ -22,6 +22,7 @@ def applicable_task_names task_names.delete("matching_details") unless matching_claims.exists? task_names.delete("payroll_gender") unless claim.payroll_gender_missing? || task_names_for_claim.include?("payroll_gender") task_names.delete("visa") unless claim.policy.international_relocation_payments? + task_names.delete("arrival_date") unless claim.policy.international_relocation_payments? end end diff --git a/app/models/policies/international_relocation_payments/admin_tasks_presenter.rb b/app/models/policies/international_relocation_payments/admin_tasks_presenter.rb index 9e7f35fddd..0515388e16 100644 --- a/app/models/policies/international_relocation_payments/admin_tasks_presenter.rb +++ b/app/models/policies/international_relocation_payments/admin_tasks_presenter.rb @@ -9,6 +9,12 @@ def initialize(claim) @claim = claim end + def arrival_date + [ + ["Arrival date", eligibility.date_of_entry.to_fs(:govuk_date)] + ] + end + def identity_confirmation [ ["Nationality", eligibility.nationality], diff --git a/app/models/task.rb b/app/models/task.rb index b2d48af068..289eb29061 100644 --- a/app/models/task.rb +++ b/app/models/task.rb @@ -18,6 +18,7 @@ class Task < ApplicationRecord payroll_details matching_details payroll_gender + arrival_date visa ].freeze diff --git a/app/views/admin/tasks/arrival_date.html.erb b/app/views/admin/tasks/arrival_date.html.erb new file mode 100644 index 0000000000..1fbe12d7b3 --- /dev/null +++ b/app/views/admin/tasks/arrival_date.html.erb @@ -0,0 +1,25 @@ +<% content_for(:page_title) { page_title("Claim #{@claim.reference} arrival date check for #{@claim.policy.short_name}") } %> +<%= link_to "Back", admin_claim_tasks_path(claim_id: @claim.id), class: "govuk-back-link" %> +<%= render "shared/error_summary", instance: @task, errored_field_id_overrides: { "passed": "task_passed_true" } if @task.errors.any? %> + +
+ <%= render "claim_summary", claim: @claim, heading: "Arrival date" %> + +
+

<%= @current_task_name.humanize %>

+
+ +
+ <%= render "admin/claims/answers", answers: @tasks_presenter.arrival_date %> +
+ +
+ <% if !@task.passed.nil? %> + <%= render "task_outcome", task: @task %> + <% else %> + <%= render "form", task_name: "arrival_date", claim: @claim %> + <% end %> + + <%= render partial: "admin/task_pagination" %> +
+
diff --git a/config/initializers/date_formats.rb b/config/initializers/date_formats.rb index f1d9822d94..b881d0c7e7 100644 --- a/config/initializers/date_formats.rb +++ b/config/initializers/date_formats.rb @@ -1 +1,2 @@ DateTime::DATE_FORMATS[:custom_ordinal] = lambda { |time| time.strftime("%A #{time.day.ordinalize} %B %Y") } +DateTime::DATE_FORMATS[:govuk_date] = lambda { |time| time.strftime("%d-%m-%Y") } diff --git a/config/locales/en.yml b/config/locales/en.yml index d989bfee03..98f52827ee 100644 --- a/config/locales/en.yml +++ b/config/locales/en.yml @@ -121,6 +121,7 @@ en: claim_route_with_tid: "Signed in with DfE Identity" passport_number: "Passport number" nationality: "Nationality" + arrival_date: "Date of entry" decision: created_at: "Created at" result: "Result" @@ -154,6 +155,7 @@ en: payroll_details: "Check bank/building society account details" census_subjects_taught: "Check eligible subjects are taught" visa: "Check visa" + arrival_date: "Check arrival date" undo_decision: approved: "Undo approval" rejected: "Undo rejection" @@ -783,6 +785,8 @@ en: title: "Did %{claim_full_name} submit the claim?" visa: title: "Is the claimant’s visa type eligible for a claim?" + arrival_date: + title: "Does the claimant’s arrival date match the above information from their claim?" further_education_payments: landing_page: Find out if you are eligible for any incentive payments for further education teachers diff --git a/spec/factories/policies/international_relocation_payments/eligibilities.rb b/spec/factories/policies/international_relocation_payments/eligibilities.rb index 305c19a952..8f33b3116a 100644 --- a/spec/factories/policies/international_relocation_payments/eligibilities.rb +++ b/spec/factories/policies/international_relocation_payments/eligibilities.rb @@ -6,6 +6,7 @@ end trait :eligible do + eligible_date_of_entry eligible_home_office eligible_school end @@ -13,5 +14,9 @@ trait :eligible_school do association :current_school, factory: :school end + + trait :eligible_date_of_entry do + date_of_entry { 1.year.ago } + end end end diff --git a/spec/support/admin_view_claim_feature_shared_examples.rb b/spec/support/admin_view_claim_feature_shared_examples.rb index 60616d168c..01a85ea19e 100644 --- a/spec/support/admin_view_claim_feature_shared_examples.rb +++ b/spec/support/admin_view_claim_feature_shared_examples.rb @@ -179,7 +179,7 @@ def expect_page_to_have_policy_sections(policy) when Policies::EarlyCareerPayments ["Identity confirmation", "Qualifications", "Induction confirmation", "Census subjects taught", "Employment", "Student loan plan", "Decision"] when Policies::InternationalRelocationPayments - ["Identity confirmation", "Visa", "Decision"] + ["Identity confirmation", "Visa", "Arrival date", "Decision"] else raise "Unimplemented policy: #{policy}" end From d5b47fb9c5b537c9787e723d9b1e9d1547805e02 Mon Sep 17 00:00:00 2001 From: Kenneth Lee Date: Thu, 27 Jun 2024 16:07:48 +0100 Subject: [PATCH 63/66] FE landing page tweaks * Use govuk-component helpers * Add FE provider link to file --- .../landing_page.html.erb | 48 +++++++++---------- 1 file changed, 24 insertions(+), 24 deletions(-) diff --git a/app/views/further_education_payments/landing_page.html.erb b/app/views/further_education_payments/landing_page.html.erb index eac4c254f3..c9fc8571ce 100644 --- a/app/views/further_education_payments/landing_page.html.erb +++ b/app/views/further_education_payments/landing_page.html.erb @@ -10,28 +10,28 @@ Before starting your application, it may be useful to have the following information to hand:

-
    -
  • your contract or written statement of employment
  • -
  • your teaching timetable
  • -
  • the name of your college or sixth-form group, if your further education (FE) provider is part of one
  • -
+ <%= govuk_list [ + "your contract or written statement of employment", + "your teaching timetable", + "the name of your college or sixth-form group, if your further education (FE) provider is part of one" + ], type: :bullet %>

Answering questions about eligibility takes [TBC] minutes and applying for the payment takes another [TBC] minutes.

-
+ <%= govuk_inset_text do %>

You’ll need a GOV.UK One Login account to apply for a further education financial incentive payment. If you don’t have an account yet, we’ll help you create one.

To create a GOV.UK One Login, you’ll need:

-
    -
  • an email address
  • -
  • a way to get security codes - this can be a mobile phone number or an authenticator app
  • -
-
+ <%= govuk_list [ + "an email address", + "a way to get security codes - this can be a mobile phone number or an authenticator app" + ], type: :bullet %> + <% end %> <%# TODO: There isn't any journey closed content, for now hide the button %> <% if @journey_open %> @@ -54,15 +54,15 @@ Claimants should be in the first 5 years of their teaching career in England and teach specific courses in the following subject areas:

-
    -
  • building and construction
  • -
  • chemistry
  • -
  • computing, including digital and ICT
  • -
  • early years
  • -
  • engineering and manufacturing, including transport engineering and electronics
  • -
  • maths
  • -
  • physics
  • -
+ <%= govuk_list [ + "building and construction", + "chemistry", + "computing, including digital and ICT", + "early years", + "engineering and manufacturing, including transport engineering and electronics", + "maths", + "physics" + ], type: :bullet %>

Further information about the eligibility criteria can be found in the <%= govuk_link_to "levelling up premium payments for FE teachers guidance", "https://www.gov.uk/guidance/levelling-up-premium-payments-for-fe-teachers", target: "_blank" %>. @@ -74,10 +74,10 @@ If you meet the eligibility criteria, you could be eligible for between £2,000 and £6,000. The amount you are eligible for depends on:

-
    -
  • <%= govuk_link_to "the FE provider you teach in [TBC]" %>
  • -
  • the number of hours you teach
  • -
+ <%= govuk_list [ + govuk_link_to("the FE provider you teach in", "https://assets.publishing.service.gov.uk/media/667300fe64e554df3bd0db92/List_of_eligible_FE_providers_and_payment_value_for_levelling_up_premium.xlsx"), + "the number of hours you teach" + ], type: :bullet %>

The incentive payment is taxable income, so the amount you receive may be lower following tax deductions. If you are currently paying off a student loan, a deduction from your payment will also go towards repaying it. From 20cf947dfac2b766f593903af7cbda261be0d5c4 Mon Sep 17 00:00:00 2001 From: Kenneth Lee Date: Thu, 27 Jun 2024 18:52:47 +0100 Subject: [PATCH 64/66] LUPEYALPHA-553 - add half-teaching-hours page/form to FE journey --- .../half_teaching_hours_form.rb | 27 +++++++++ .../journeys/further_education_payments.rb | 3 +- .../session_answers.rb | 1 + .../claims/half_teaching_hours.html.erb | 29 ++++++++-- .../claims/teaching_responsibilities.html.erb | 4 +- config/locales/en.yml | 3 + .../happy_js_path_spec.rb | 3 +- .../happy_path_spec.rb | 3 +- .../half_teaching_hours_form_spec.rb | 58 +++++++++++++++++++ 9 files changed, 120 insertions(+), 11 deletions(-) create mode 100644 app/forms/journeys/further_education_payments/half_teaching_hours_form.rb create mode 100644 spec/forms/journeys/further_education_payments/half_teaching_hours_form_spec.rb diff --git a/app/forms/journeys/further_education_payments/half_teaching_hours_form.rb b/app/forms/journeys/further_education_payments/half_teaching_hours_form.rb new file mode 100644 index 0000000000..8d540e34b5 --- /dev/null +++ b/app/forms/journeys/further_education_payments/half_teaching_hours_form.rb @@ -0,0 +1,27 @@ +module Journeys + module FurtherEducationPayments + class HalfTeachingHoursForm < Form + attribute :half_teaching_hours, :boolean + + validates :half_teaching_hours, + inclusion: { + in: [true, false], + message: i18n_error_message(:inclusion) + } + + def radio_options + [ + OpenStruct.new(id: true, name: "Yes"), + OpenStruct.new(id: false, name: "No") + ] + end + + def save + return false unless valid? + + journey_session.answers.assign_attributes(half_teaching_hours:) + journey_session.save! + end + end + end +end diff --git a/app/models/journeys/further_education_payments.rb b/app/models/journeys/further_education_payments.rb index 0a417d8184..dce4f4a286 100644 --- a/app/models/journeys/further_education_payments.rb +++ b/app/models/journeys/further_education_payments.rb @@ -19,7 +19,8 @@ module FurtherEducationPayments "teaching-qualification" => TeachingQualificationForm, "poor-performance" => PoorPerformanceForm, "check-your-answers" => CheckYourAnswersForm, - "ineligible" => IneligibleForm + "ineligible" => IneligibleForm, + "half-teaching-hours" => HalfTeachingHoursForm } } end diff --git a/app/models/journeys/further_education_payments/session_answers.rb b/app/models/journeys/further_education_payments/session_answers.rb index 3ef62aa669..5655f7d3f4 100644 --- a/app/models/journeys/further_education_payments/session_answers.rb +++ b/app/models/journeys/further_education_payments/session_answers.rb @@ -11,6 +11,7 @@ class SessionAnswers < Journeys::SessionAnswers attribute :teaching_qualification, :string attribute :subject_to_formal_performance_action, :boolean attribute :subject_to_disciplinary_action, :boolean + attribute :half_teaching_hours, :boolean def school @school ||= School.find(school_id) diff --git a/app/views/further_education_payments/claims/half_teaching_hours.html.erb b/app/views/further_education_payments/claims/half_teaching_hours.html.erb index fba0dba654..5a56a778e6 100644 --- a/app/views/further_education_payments/claims/half_teaching_hours.html.erb +++ b/app/views/further_education_payments/claims/half_teaching_hours.html.erb @@ -1,7 +1,24 @@ -

- FE half teaching hours goes here -

+
+
+ <%= form_with model: @form, url: claim_path(current_journey_routing_name), method: :patch, builder: GOVUKDesignSystemFormBuilder::FormBuilder, html: { novalidate: false } do |f| %> + <%= f.govuk_error_summary %> -<%= form_with model: @form, url: claim_path(current_journey_routing_name), method: :patch, builder: GOVUKDesignSystemFormBuilder::FormBuilder, html: { novalidate: false } do |f| %> - <%= f.govuk_submit %> -<% end %> +

+ Are at least half of your timetabled teaching hours spent teaching 16 to 19-year-olds, including those up to age 25 with an Education, Health and Care Plan (EHCP)? +

+ +

+ To apply, at least 50% of your timetabled teaching hours must include either: +

+ + <%= govuk_list [ + "a student aged 16 to 19", + "a person up to age 25 with an #{govuk_link_to("Education, Health and Care Plan (EHCP)", "https://www.gov.uk/children-with-special-educational-needs/extra-SEN-help", target: "_blank")}".html_safe + ], type: :bullet %> + + <%= f.govuk_collection_radio_buttons :half_teaching_hours, @form.radio_options, :id, :name, legend: { hidden: true } %> + + <%= f.govuk_submit %> + <% end %> +
+
diff --git a/app/views/further_education_payments/claims/teaching_responsibilities.html.erb b/app/views/further_education_payments/claims/teaching_responsibilities.html.erb index 335934096b..31b343b3f5 100644 --- a/app/views/further_education_payments/claims/teaching_responsibilities.html.erb +++ b/app/views/further_education_payments/claims/teaching_responsibilities.html.erb @@ -23,8 +23,8 @@ "tutor" ], type: :bullet %> - <%= f.govuk_collection_radio_buttons :teaching_responsibilities, @form.radio_options, :id, :name, - legend: { text: "Are you a member of staff with teaching responsibilities?" } %> + <%= f.govuk_collection_radio_buttons :teaching_responsibilities, @form.radio_options, :id, :name, + legend: { text: "Are you a member of staff with teaching responsibilities?" } %> <%= f.govuk_submit %> <% end %> diff --git a/config/locales/en.yml b/config/locales/en.yml index 98f52827ee..5a793f3aef 100644 --- a/config/locales/en.yml +++ b/config/locales/en.yml @@ -841,6 +841,9 @@ en: inclusion: Select yes if you are subject to formal action for poor performance at work disciplinary: inclusion: Select yes if you are subject to disciplinary action + half_teaching_hours: + errors: + inclusion: Select yes if at least half your timetabled teaching hours are spent teaching 16-19-year-olds, including those up to 25 with an Education, Health and Care Plan activerecord: errors: models: diff --git a/spec/features/further_education_payments/happy_js_path_spec.rb b/spec/features/further_education_payments/happy_js_path_spec.rb index 31f3c45586..ded799408f 100644 --- a/spec/features/further_education_payments/happy_js_path_spec.rb +++ b/spec/features/further_education_payments/happy_js_path_spec.rb @@ -48,7 +48,8 @@ expect(page).to have_content("FE teaching courses goes here") click_button "Continue" - expect(page).to have_content("FE half teaching hours goes here") + expect(page).to have_content("Are at least half of your timetabled teaching hours spent teaching 16 to 19-year-olds, including those up to age 25 with an Education, Health and Care Plan (EHCP)?") + choose "Yes" click_button "Continue" expect(page).to have_content("Do you have a teaching qualification?") diff --git a/spec/features/further_education_payments/happy_path_spec.rb b/spec/features/further_education_payments/happy_path_spec.rb index 66d673dbe8..06a9feb9f6 100644 --- a/spec/features/further_education_payments/happy_path_spec.rb +++ b/spec/features/further_education_payments/happy_path_spec.rb @@ -45,7 +45,8 @@ expect(page).to have_content("FE teaching courses goes here") click_button "Continue" - expect(page).to have_content("FE half teaching hours goes here") + expect(page).to have_content("Are at least half of your timetabled teaching hours spent teaching 16 to 19-year-olds, including those up to age 25 with an Education, Health and Care Plan (EHCP)?") + choose "Yes" click_button "Continue" expect(page).to have_content("Do you have a teaching qualification?") diff --git a/spec/forms/journeys/further_education_payments/half_teaching_hours_form_spec.rb b/spec/forms/journeys/further_education_payments/half_teaching_hours_form_spec.rb new file mode 100644 index 0000000000..e23d1c1be6 --- /dev/null +++ b/spec/forms/journeys/further_education_payments/half_teaching_hours_form_spec.rb @@ -0,0 +1,58 @@ +require "rails_helper" + +RSpec.describe Journeys::FurtherEducationPayments::HalfTeachingHoursForm, type: :model do + let(:journey) { Journeys::FurtherEducationPayments } + let(:journey_session) { create(:further_education_payments_session) } + + let(:params) do + ActionController::Parameters.new( + claim: { + half_teaching_hours: + } + ) + end + + subject do + described_class.new( + journey_session:, + journey:, + params: + ) + end + + describe "validations" do + let(:half_teaching_hours) { nil } + + it do + is_expected.not_to( + allow_value(nil) + .for(:half_teaching_hours) + .with_message("Select yes if at least half your timetabled teaching hours are spent teaching 16-19-year-olds, including those up to 25 with an Education, Health and Care Plan") + ) + end + end + + describe "#save" do + context "Yes" do + let(:half_teaching_hours) { true } + + it "updates the journey session" do + expect { expect(subject.save).to be(true) }.to( + change { journey_session.reload.answers.half_teaching_hours } + .to(true) + ) + end + end + + context "No" do + let(:half_teaching_hours) { false } + + it "updates the journey session" do + expect { expect(subject.save).to be(true) }.to( + change { journey_session.reload.answers.half_teaching_hours } + .to(false) + ) + end + end + end +end From 76d243de86a39d253a196a7f2bf487d8af5c8f78 Mon Sep 17 00:00:00 2001 From: Felix Clack Date: Wed, 3 Jul 2024 08:19:58 +0100 Subject: [PATCH 65/66] Add the employment task for IRP claims We want admins to be able to confirm the employment details of a claim as part of the tasks to approve a claim. --- app/models/claim_checking_tasks.rb | 2 +- .../admin_tasks_presenter.rb | 6 ++++++ config/locales/en.yml | 2 ++ spec/support/admin_view_claim_feature_shared_examples.rb | 2 +- 4 files changed, 10 insertions(+), 2 deletions(-) diff --git a/app/models/claim_checking_tasks.rb b/app/models/claim_checking_tasks.rb index 6cce65f32a..df2a7c49ef 100644 --- a/app/models/claim_checking_tasks.rb +++ b/app/models/claim_checking_tasks.rb @@ -12,7 +12,7 @@ def initialize(claim) delegate :policy, to: :claim def applicable_task_names - return %w[identity_confirmation visa arrival_date] if policy.international_relocation_payments? + return %w[identity_confirmation visa arrival_date employment] if policy.international_relocation_payments? @applicable_task_names ||= Task::NAMES.dup.tap do |task_names| task_names.delete("induction_confirmation") unless claim.policy == Policies::EarlyCareerPayments diff --git a/app/models/policies/international_relocation_payments/admin_tasks_presenter.rb b/app/models/policies/international_relocation_payments/admin_tasks_presenter.rb index 0515388e16..35f6cec0f1 100644 --- a/app/models/policies/international_relocation_payments/admin_tasks_presenter.rb +++ b/app/models/policies/international_relocation_payments/admin_tasks_presenter.rb @@ -15,6 +15,12 @@ def arrival_date ] end + def employment + [ + [translate("admin.current_school"), display_school(eligibility.current_school)] + ] + end + def identity_confirmation [ ["Nationality", eligibility.nationality], diff --git a/config/locales/en.yml b/config/locales/en.yml index 98f52827ee..7ae775bbfa 100644 --- a/config/locales/en.yml +++ b/config/locales/en.yml @@ -787,6 +787,8 @@ en: title: "Is the claimant’s visa type eligible for a claim?" arrival_date: title: "Does the claimant’s arrival date match the above information from their claim?" + employment: + title: "Does the claimant’s current school match the above information from their claim?" further_education_payments: landing_page: Find out if you are eligible for any incentive payments for further education teachers diff --git a/spec/support/admin_view_claim_feature_shared_examples.rb b/spec/support/admin_view_claim_feature_shared_examples.rb index 01a85ea19e..67cbc3cc5e 100644 --- a/spec/support/admin_view_claim_feature_shared_examples.rb +++ b/spec/support/admin_view_claim_feature_shared_examples.rb @@ -179,7 +179,7 @@ def expect_page_to_have_policy_sections(policy) when Policies::EarlyCareerPayments ["Identity confirmation", "Qualifications", "Induction confirmation", "Census subjects taught", "Employment", "Student loan plan", "Decision"] when Policies::InternationalRelocationPayments - ["Identity confirmation", "Visa", "Arrival date", "Decision"] + ["Identity confirmation", "Visa", "Arrival date", "Employment", "Decision"] else raise "Unimplemented policy: #{policy}" end From 4823ca222d79774c4e442fab385ad44c5469fd2c Mon Sep 17 00:00:00 2001 From: Felix Clack Date: Wed, 3 Jul 2024 08:29:14 +0100 Subject: [PATCH 66/66] Add an employment contract task to the admin The IRP journey includes a question asking if the claimant's contract is at least 12 months. We want an admin task to confirm this answer. --- app/models/claim_checking_tasks.rb | 3 ++- .../admin_tasks_presenter.rb | 6 +++++ app/models/task.rb | 1 + .../admin/tasks/employment_contract.html.erb | 27 +++++++++++++++++++ config/locales/en.yml | 3 +++ .../eligibilities.rb | 5 ++++ ...dmin_view_claim_feature_shared_examples.rb | 2 +- 7 files changed, 45 insertions(+), 2 deletions(-) create mode 100644 app/views/admin/tasks/employment_contract.html.erb diff --git a/app/models/claim_checking_tasks.rb b/app/models/claim_checking_tasks.rb index df2a7c49ef..2b495e8c1b 100644 --- a/app/models/claim_checking_tasks.rb +++ b/app/models/claim_checking_tasks.rb @@ -12,7 +12,7 @@ def initialize(claim) delegate :policy, to: :claim def applicable_task_names - return %w[identity_confirmation visa arrival_date employment] if policy.international_relocation_payments? + return %w[identity_confirmation visa arrival_date employment employment_contract] if policy.international_relocation_payments? @applicable_task_names ||= Task::NAMES.dup.tap do |task_names| task_names.delete("induction_confirmation") unless claim.policy == Policies::EarlyCareerPayments @@ -23,6 +23,7 @@ def applicable_task_names task_names.delete("payroll_gender") unless claim.payroll_gender_missing? || task_names_for_claim.include?("payroll_gender") task_names.delete("visa") unless claim.policy.international_relocation_payments? task_names.delete("arrival_date") unless claim.policy.international_relocation_payments? + task_names.delete("employment_contract") unless claim.policy.international_relocation_payments? end end diff --git a/app/models/policies/international_relocation_payments/admin_tasks_presenter.rb b/app/models/policies/international_relocation_payments/admin_tasks_presenter.rb index 35f6cec0f1..16e87daf3a 100644 --- a/app/models/policies/international_relocation_payments/admin_tasks_presenter.rb +++ b/app/models/policies/international_relocation_payments/admin_tasks_presenter.rb @@ -21,6 +21,12 @@ def employment ] end + def employment_contract + [ + ["Employment contract at least one year", eligibility.one_year?] + ] + end + def identity_confirmation [ ["Nationality", eligibility.nationality], diff --git a/app/models/task.rb b/app/models/task.rb index 289eb29061..c0a9e165cd 100644 --- a/app/models/task.rb +++ b/app/models/task.rb @@ -19,6 +19,7 @@ class Task < ApplicationRecord matching_details payroll_gender arrival_date + employment_contract visa ].freeze diff --git a/app/views/admin/tasks/employment_contract.html.erb b/app/views/admin/tasks/employment_contract.html.erb new file mode 100644 index 0000000000..08a9e683b0 --- /dev/null +++ b/app/views/admin/tasks/employment_contract.html.erb @@ -0,0 +1,27 @@ +<% content_for(:page_title) { page_title("Claim #{@claim.reference} employment contract check for #{@claim.policy.short_name}") } %> +<%= link_to "Back", admin_claim_tasks_path(claim_id: @claim.id), class: "govuk-back-link" %> +<%= render "shared/error_summary", instance: @task, errored_field_id_overrides: { "passed": "task_passed_true" } if @task.errors.any? %> + +
+ <%= render "claim_summary", claim: @claim, heading: "Employment contract check" %> + +
+

<%= @current_task_name.humanize %>

+
+ +
+ <%= render "admin/claims/answers", answers: @tasks_presenter.employment_contract %> +
+ +
+ <% if !@task.passed.nil? %> + <%= render "task_outcome", task: @task %> + <% else %> + <%= render "form", task_name: "employment_contract", claim: @claim %> + <% end %> + + <%= render partial: "admin/task_pagination" %> +
+
+ + diff --git a/config/locales/en.yml b/config/locales/en.yml index 8105dee289..240b6bf473 100644 --- a/config/locales/en.yml +++ b/config/locales/en.yml @@ -156,6 +156,7 @@ en: census_subjects_taught: "Check eligible subjects are taught" visa: "Check visa" arrival_date: "Check arrival date" + employment_contract: "Check employment contract" undo_decision: approved: "Undo approval" rejected: "Undo rejection" @@ -789,6 +790,8 @@ en: title: "Does the claimant’s arrival date match the above information from their claim?" employment: title: "Does the claimant’s current school match the above information from their claim?" + employment_contract: + title: "Does the claimant’s employment contract match the above information from their claim?" further_education_payments: landing_page: Find out if you are eligible for any incentive payments for further education teachers diff --git a/spec/factories/policies/international_relocation_payments/eligibilities.rb b/spec/factories/policies/international_relocation_payments/eligibilities.rb index 8f33b3116a..5ac60aba1f 100644 --- a/spec/factories/policies/international_relocation_payments/eligibilities.rb +++ b/spec/factories/policies/international_relocation_payments/eligibilities.rb @@ -6,6 +6,7 @@ end trait :eligible do + eligible_contract eligible_date_of_entry eligible_home_office eligible_school @@ -18,5 +19,9 @@ trait :eligible_date_of_entry do date_of_entry { 1.year.ago } end + + trait :eligible_contract do + one_year { true } + end end end diff --git a/spec/support/admin_view_claim_feature_shared_examples.rb b/spec/support/admin_view_claim_feature_shared_examples.rb index 67cbc3cc5e..59a00ae4b1 100644 --- a/spec/support/admin_view_claim_feature_shared_examples.rb +++ b/spec/support/admin_view_claim_feature_shared_examples.rb @@ -179,7 +179,7 @@ def expect_page_to_have_policy_sections(policy) when Policies::EarlyCareerPayments ["Identity confirmation", "Qualifications", "Induction confirmation", "Census subjects taught", "Employment", "Student loan plan", "Decision"] when Policies::InternationalRelocationPayments - ["Identity confirmation", "Visa", "Arrival date", "Employment", "Decision"] + ["Identity confirmation", "Visa", "Arrival date", "Employment", "Employment contract", "Decision"] else raise "Unimplemented policy: #{policy}" end