diff --git a/app/forms/journeys/additional_payments_for_teaching/eligible_itt_subject_form.rb b/app/forms/journeys/additional_payments_for_teaching/eligible_itt_subject_form.rb
index 1904af7ab6..199a069f0a 100644
--- a/app/forms/journeys/additional_payments_for_teaching/eligible_itt_subject_form.rb
+++ b/app/forms/journeys/additional_payments_for_teaching/eligible_itt_subject_form.rb
@@ -50,7 +50,7 @@ def chemistry_or_physics_available?
def subject_symbols
@subject_symbols ||=
- JourneySubjectEligibilityChecker.selectable_subject_symbols(answers)
+ AdditionalPaymentsForTeaching.selectable_subject_symbols(journey_session)
end
def save
diff --git a/app/forms/journeys/additional_payments_for_teaching/itt_academic_year_form.rb b/app/forms/journeys/additional_payments_for_teaching/itt_academic_year_form.rb
index 0226d9a6ab..f07c26c4a1 100644
--- a/app/forms/journeys/additional_payments_for_teaching/itt_academic_year_form.rb
+++ b/app/forms/journeys/additional_payments_for_teaching/itt_academic_year_form.rb
@@ -28,7 +28,7 @@ def qualification_is?(*symbols)
end
def selectable_itt_years_for_claim_year
- JourneySubjectEligibilityChecker.selectable_itt_years_for_claim_year(
+ AdditionalPaymentsForTeaching.selectable_itt_years_for_claim_year(
journey.configuration.current_academic_year
)
end
diff --git a/app/forms/journeys/additional_payments_for_teaching/nqt_in_academic_year_after_itt_form.rb b/app/forms/journeys/additional_payments_for_teaching/nqt_in_academic_year_after_itt_form.rb
index c851cee4ed..7e3ecb013b 100644
--- a/app/forms/journeys/additional_payments_for_teaching/nqt_in_academic_year_after_itt_form.rb
+++ b/app/forms/journeys/additional_payments_for_teaching/nqt_in_academic_year_after_itt_form.rb
@@ -1,8 +1,6 @@
module Journeys
module AdditionalPaymentsForTeaching
class NqtInAcademicYearAfterIttForm < Form
- include EligibilityCheckable
-
attribute :nqt_in_academic_year_after_itt, :boolean
validates :nqt_in_academic_year_after_itt, inclusion: {in: [true, false], message: i18n_error_message(:inclusion)}
@@ -23,6 +21,10 @@ def save
private
+ def trainee_teacher?
+ nqt_in_academic_year_after_itt == false
+ end
+
def determine_induction_answer_from_dqt_record
return unless passed_details_check_with_teacher_id?
# We can derive the induction_completed value for current_claim using the
diff --git a/app/helpers/claims/itt_subject_helper.rb b/app/helpers/claims/itt_subject_helper.rb
index 5cd55a0fda..07ad7d2d31 100644
--- a/app/helpers/claims/itt_subject_helper.rb
+++ b/app/helpers/claims/itt_subject_helper.rb
@@ -1,10 +1,11 @@
-require "journey_subject_eligibility_checker"
-
module Claims
module IttSubjectHelper
def subjects_to_sentence_for_hint_text(answers)
- all_ecp_subjects = [:chemistry, :foreign_languages, :mathematics, :physics]
- all_lup_subjects = JourneySubjectEligibilityChecker.fixed_lup_subject_symbols
+ all_ecp_subjects = Policies::EarlyCareerPayments.subject_symbols(
+ claim_year: answers.policy_year,
+ itt_year: answers.itt_academic_year
+ )
+ all_lup_subjects = Policies::LevellingUpPremiumPayments.fixed_subject_symbols
hint_subject_symbols = Set[]
diff --git a/app/models/academic_year.rb b/app/models/academic_year.rb
index a0588564e7..6aca6d23d8 100644
--- a/app/models/academic_year.rb
+++ b/app/models/academic_year.rb
@@ -67,6 +67,12 @@ def for(date)
new(date.year)
end
end
+
+ def wrap(value)
+ return value if value.is_a? AcademicYear
+
+ new(value)
+ end
end
def initialize(year_or_academic_year_or_string = nil)
@@ -101,8 +107,12 @@ def eql?(other)
to_s == other.to_s
end
+ def none?
+ [start_year, end_year].include? nil
+ end
+
def to_s(format = :default)
- return "None" if [start_year, end_year].include? nil
+ return "None" if none?
if format == :long
"#{start_year} to #{end_year}"
diff --git a/app/models/concerns/eligibility_checkable.rb b/app/models/concerns/eligibility_checkable.rb
index b5decfc117..f2b769667f 100644
--- a/app/models/concerns/eligibility_checkable.rb
+++ b/app/models/concerns/eligibility_checkable.rb
@@ -3,7 +3,6 @@ module EligibilityCheckable
FIRST_COMBINED_ECP_AND_LUP_POLICY_YEAR = AcademicYear.new(2022)
FINAL_COMBINED_ECP_AND_LUP_POLICY_YEAR = AcademicYear.new(2024)
- FINAL_LUP_POLICY_YEAR = AcademicYear.new(2025)
COMBINED_ECP_AND_LUP_POLICY_YEARS = FIRST_COMBINED_ECP_AND_LUP_POLICY_YEAR..FINAL_COMBINED_ECP_AND_LUP_POLICY_YEAR
COMBINED_ECP_AND_LUP_POLICY_YEARS_BEFORE_FINAL_YEAR = FIRST_COMBINED_ECP_AND_LUP_POLICY_YEAR...FINAL_COMBINED_ECP_AND_LUP_POLICY_YEAR
@@ -50,7 +49,19 @@ def trainee_teacher?
private
def common_ineligible_attributes?
- [indicated_ineligible_school?, trainee_teacher?, supply_teacher_lacking_either_long_contract_or_direct_employment?, poor_performance?, no_selectable_subjects?, ineligible_cohort?, insufficient_teaching?].any?
+ [
+ policy_closed?,
+ indicated_ineligible_school?,
+ supply_teacher_lacking_either_long_contract_or_direct_employment?,
+ poor_performance?,
+ no_selectable_subjects?,
+ ineligible_cohort?,
+ insufficient_teaching?
+ ].any?
+ end
+
+ def policy_closed?
+ policy.closed?(claim_year)
end
def indicated_ineligible_school?
@@ -66,19 +77,20 @@ def poor_performance?
end
def no_selectable_subjects?
- args = {claim_year: claim_year, itt_year: itt_academic_year}
-
- if args.values.any?(&:blank?)
+ if claim_year.blank? || itt_academic_year.blank?
false
else
- JourneySubjectEligibilityChecker.new(**args).current_and_future_subject_symbols(policy).empty?
+ policy.current_and_future_subject_symbols(
+ claim_year: claim_year,
+ itt_year: itt_academic_year
+ ).empty?
end
end
def ineligible_cohort?
return false if itt_academic_year.nil?
- eligible_itt_years = JourneySubjectEligibilityChecker.selectable_itt_years_for_claim_year(claim_year)
+ eligible_itt_years = policy.selectable_itt_years_for_claim_year(claim_year)
!itt_academic_year.in? eligible_itt_years
end
@@ -113,7 +125,7 @@ def good_performance?
def eligible_cohort?
return false if itt_academic_year.nil?
- eligible_itt_years = JourneySubjectEligibilityChecker.selectable_itt_years_for_claim_year(claim_year)
+ eligible_itt_years = policy.selectable_itt_years_for_claim_year(claim_year)
itt_academic_year.in? eligible_itt_years
end
diff --git a/app/models/concerns/policies/early_career_payments/eligible.rb b/app/models/concerns/policies/early_career_payments/eligible.rb
deleted file mode 100644
index 6899541abb..0000000000
--- a/app/models/concerns/policies/early_career_payments/eligible.rb
+++ /dev/null
@@ -1,94 +0,0 @@
-module Policies
- module EarlyCareerPayments
- module Eligible
- def policy
- Policies::EarlyCareerPayments
- end
-
- def induction_not_completed?
- !induction_completed.nil? && !induction_completed?
- end
-
- def ecp_only_school?
- Policies::EarlyCareerPayments::SchoolEligibility.new(current_school).eligible? &&
- !Policies::LevellingUpPremiumPayments::SchoolEligibility.new(current_school).eligible?
- end
-
- def calculate_award_amount
- return 0 if eligible_itt_subject.blank?
-
- args = {policy_year: claim_year, itt_year: itt_academic_year, subject_symbol: eligible_itt_subject.to_sym, school: current_school}
-
- if args.values.any?(&:blank?)
- 0
- else
- Policies::EarlyCareerPayments::AwardAmountCalculator.new(**args).amount_in_pounds
- end
- end
-
- private
-
- def specific_eligible_now_attributes?
- induction_completed? && itt_subject_eligible_now?
- end
-
- def itt_subject_eligible_now?
- itt_subject = eligible_itt_subject # attribute name implies eligibility which isn't always the case
- return false if itt_subject.blank?
- return false if itt_subject_none_of_the_above?
-
- itt_subject_checker = JourneySubjectEligibilityChecker.new(claim_year: claim_year, itt_year: itt_academic_year)
- itt_subject.to_sym.in?(itt_subject_checker.current_subject_symbols(policy))
- end
-
- def specific_ineligible_attributes?
- 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?
- itt_subject = eligible_itt_subject # attribute name implies eligibility which isn't always the case
- return false if itt_subject.blank?
- return true if itt_subject_none_of_the_above?
-
- itt_subject_checker = JourneySubjectEligibilityChecker.new(claim_year: claim_year, itt_year: itt_academic_year)
- !itt_subject.to_sym.in?(itt_subject_checker.current_and_future_subject_symbols(policy))
- end
-
- def specific_eligible_later_attributes?
- newly_qualified_teacher? && ((induction_not_completed? && any_future_policy_years?) || (!itt_subject_eligible_now? && itt_subject_eligible_later?))
- end
-
- def itt_subject_eligible_later?
- itt_subject = eligible_itt_subject # attribute name implies eligibility which isn't always the case
- return false if itt_subject.blank?
- return false if itt_subject_none_of_the_above?
-
- itt_subject_checker = JourneySubjectEligibilityChecker.new(claim_year: claim_year, itt_year: itt_academic_year)
- itt_subject.to_sym.in?(itt_subject_checker.future_subject_symbols(policy))
- end
-
- # TODO: Is this used anywhere?
- def itt_subject_ineligible?
- return false if claim_year.blank?
-
- itt_subject_other_than_those_eligible_now_or_in_the_future?
- end
-
- def itt_subject_other_than_those_eligible_now_or_in_the_future?
- itt_subject = eligible_itt_subject # attribute name implies eligibility which isn't always the case
- return false if itt_subject.blank?
-
- args = {claim_year: claim_year, itt_year: itt_academic_year}
-
- if args.any?(&:blank?)
- # can still rule some out
- itt_subject_none_of_the_above?
- else
- itt_subject_checker = JourneySubjectEligibilityChecker.new(**args)
- itt_subject_symbol = itt_subject.to_sym
- !itt_subject_symbol.in?(itt_subject_checker.current_and_future_subject_symbols(policy))
- end
- end
- end
- end
-end
diff --git a/app/models/concerns/policies/levelling_up_premium_payments/eligible.rb b/app/models/concerns/policies/levelling_up_premium_payments/eligible.rb
deleted file mode 100644
index 6ca6bbb858..0000000000
--- a/app/models/concerns/policies/levelling_up_premium_payments/eligible.rb
+++ /dev/null
@@ -1,87 +0,0 @@
-module Policies
- module LevellingUpPremiumPayments
- module Eligible
- def policy
- Policies::LevellingUpPremiumPayments
- end
-
- def indicated_ineligible_itt_subject?
- return false if eligible_itt_subject.blank?
-
- args = {claim_year: claim_year, itt_year: itt_academic_year}
-
- if args.values.any?(&:blank?)
- # trainee teacher who won't have given their ITT year
- eligible_itt_subject.present? && !eligible_itt_subject.to_sym.in?(JourneySubjectEligibilityChecker.fixed_lup_subject_symbols)
- else
- itt_subject_checker = JourneySubjectEligibilityChecker.new(**args)
- eligible_itt_subject.present? && !eligible_itt_subject.to_sym.in?(itt_subject_checker.current_subject_symbols(policy))
- end
- end
-
- def calculate_award_amount
- premium_payment_award&.award_amount
- end
-
- private
-
- def premium_payment_award
- return unless current_school.present?
-
- current_school.levelling_up_premium_payments_awards.find_by(
- academic_year: claim_year.to_s
- )
- end
-
- def indicated_ecp_only_itt_subject?
- eligible_itt_subject.present? && (eligible_itt_subject.to_sym == :foreign_languages)
- end
-
- def specific_eligible_now_attributes?
- eligible_itt_subject_or_relevant_degree?
- end
-
- def eligible_itt_subject_or_relevant_degree?
- good_itt_subject? || eligible_degree?
- end
-
- def good_itt_subject?
- return false if eligible_itt_subject.blank?
-
- args = {claim_year: claim_year, itt_year: itt_academic_year}
-
- if args.values.any?(&:blank?)
- # trainee teacher who won't have given their ITT year
- eligible_itt_subject.present? && eligible_itt_subject.to_sym.in?(JourneySubjectEligibilityChecker.fixed_lup_subject_symbols)
- else
- itt_subject_checker = JourneySubjectEligibilityChecker.new(**args)
- eligible_itt_subject.to_sym.in?(itt_subject_checker.current_subject_symbols(policy))
- end
- end
-
- def eligible_degree?
- eligible_degree_subject?
- end
-
- def specific_ineligible_attributes?
- indicated_ecp_only_itt_subject? || trainee_teacher_with_ineligible_itt_subject? || ineligible_itt_subject_and_no_relevant_degree?
- end
-
- def trainee_teacher_with_ineligible_itt_subject?
- trainee_teacher? && indicated_ineligible_itt_subject?
- end
-
- def ineligible_itt_subject_and_no_relevant_degree?
- indicated_ineligible_itt_subject? && lacks_eligible_degree?
- end
-
- def specific_eligible_later_attributes?
- trainee_teacher? && eligible_itt_subject_or_relevant_degree?
- end
-
- def lacks_eligible_degree?
- eligible_degree_subject == false
- end
- end
- end
-end
diff --git a/app/models/journeys/additional_payments_for_teaching.rb b/app/models/journeys/additional_payments_for_teaching.rb
index 83c2dbafb6..3b5ad6b6a3 100644
--- a/app/models/journeys/additional_payments_for_teaching.rb
+++ b/app/models/journeys/additional_payments_for_teaching.rb
@@ -30,24 +30,43 @@ module AdditionalPaymentsForTeaching
}
}.freeze
- def final_policy_year(policy)
- {
- Policies::EarlyCareerPayments => EligibilityCheckable::FINAL_COMBINED_ECP_AND_LUP_POLICY_YEAR,
- Policies::LevellingUpPremiumPayments => EligibilityCheckable::FINAL_LUP_POLICY_YEAR
- }[policy]
- end
-
def set_a_reminder?(itt_academic_year:, policy:)
policy_year = configuration.current_academic_year
- return false if policy_year >= final_policy_year(policy)
+ return false if policy_year >= policy::POLICY_END_YEAR
next_year = policy_year + 1
- eligible_itt_years = JourneySubjectEligibilityChecker.selectable_itt_years_for_claim_year(next_year)
+ eligible_itt_years = selectable_itt_years_for_claim_year(next_year)
eligible_itt_years.include?(itt_academic_year)
end
def requires_student_loan_details?
true
end
+
+ def selectable_subject_symbols(journey_session)
+ return [] if journey_session.answers.itt_academic_year&.none?
+
+ if journey_session.answers.nqt_in_academic_year_after_itt
+ EligibilityChecker.new(journey_session: journey_session)
+ .potentially_still_eligible.map do |policy|
+ policy.current_and_future_subject_symbols(
+ claim_year: journey_session.answers.policy_year,
+ itt_year: journey_session.answers.itt_academic_year
+ )
+ end.flatten.uniq
+ elsif journey_session.answers.policy_year.in?(Policies::LevellingUpPremiumPayments::POLICY_RANGE)
+ # they get the standard, unchanging LUP subject set because they won't have qualified in time for ECP by 2022/2023
+ # and they won't have given an ITT year
+ Policies::LevellingUpPremiumPayments.fixed_subject_symbols
+ else
+ []
+ end
+ end
+
+ def selectable_itt_years_for_claim_year(claim_year)
+ POLICIES.flat_map do |policy|
+ policy.selectable_itt_years_for_claim_year(claim_year)
+ end.uniq
+ end
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 3e38d921f1..ba7c80d881 100644
--- a/app/models/journeys/additional_payments_for_teaching/answers_presenter.rb
+++ b/app/models/journeys/additional_payments_for_teaching/answers_presenter.rb
@@ -157,10 +157,11 @@ def itt_academic_year
def text_for_subject_answer
policy = eligibility.policy
- subjects = JourneySubjectEligibilityChecker.new(
+
+ subjects = policy.current_and_future_subject_symbols(
claim_year: Journeys.for_policy(policy).configuration.current_academic_year,
itt_year: journey_session.answers.itt_academic_year
- ).current_and_future_subject_symbols(policy)
+ )
if subjects.many?
t("additional_payments.forms.eligible_itt_subject.answers.#{journey_session.answers.eligible_itt_subject}")
@@ -173,7 +174,10 @@ def text_for_subject_answer
private
def subject_symbols
- @subject_symbols ||= JourneySubjectEligibilityChecker.current_and_future_subject_symbols(answers)
+ @subject_symbols ||= answers.policy.subject_symbols(
+ claim_year: answers.policy_year,
+ itt_year: answers.itt_academic_year
+ )
end
def claim_submission_form
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 24871f9f85..500a5075a7 100644
--- a/app/models/journeys/additional_payments_for_teaching/slug_sequence.rb
+++ b/app/models/journeys/additional_payments_for_teaching/slug_sequence.rb
@@ -73,6 +73,15 @@ class SlugSequence
RESULTS_SLUGS
).freeze
+ TRAINEE_TEACHER_SLUGS = %w[
+ current-school
+ nqt-in-academic-year-after-itt
+ eligible-itt-subject
+ eligible-degree-subject
+ future-eligibility
+ ineligible
+ ]
+
attr_reader :journey_session
delegate :answers, to: :journey_session
@@ -81,9 +90,15 @@ def initialize(journey_session)
@journey_session = journey_session
end
- # Even though we are inside the ECP namespace, this method can modify the
- # slug sequence of both LUP and ECP claims
def slugs
+ if answers.trainee_teacher? && Policies::LevellingUpPremiumPayments::SchoolEligibility.new(answers.current_school).eligible?
+ lup_trainee_journey_slugs
+ else
+ non_trainee_journey_slugs
+ end
+ end
+
+ def non_trainee_journey_slugs
SLUGS.dup.tap do |sequence|
if !Journeys::AdditionalPaymentsForTeaching.configuration.teacher_id_enabled?
sequence.delete("sign-in-or-continue")
@@ -132,14 +147,9 @@ def slugs
sequence.delete("mobile-verification")
end
- if answers.trainee_teacher?
- trainee_teacher_slugs(sequence)
- sequence.delete("eligible-degree-subject") unless lup_eligibility_checker.indicated_ineligible_itt_subject?
- else
- sequence.delete("ineligible") unless [:ineligible, :eligible_later].include?(overall_eligibility_status)
- sequence.delete("future-eligibility")
- sequence.delete("eligible-degree-subject") unless ecp_eligibility_checker.status == :ineligible && lup_eligibility_checker.indicated_ineligible_itt_subject?
- end
+ sequence.delete("ineligible") unless [:ineligible, :eligible_later].include?(overall_eligibility_status)
+ sequence.delete("future-eligibility")
+ sequence.delete("eligible-degree-subject") unless ecp_eligibility_checker.status == :ineligible && lup_eligibility_checker.indicated_ineligible_itt_subject?
sequence.delete("induction-completed") unless induction_question_required?
@@ -164,6 +174,14 @@ def slugs
end
end
+ def lup_trainee_journey_slugs
+ TRAINEE_TEACHER_SLUGS.dup.tap do |sequence|
+ if lup_eligibility_checker.status == :eligible_later && answers.eligible_degree_subject.nil?
+ sequence.delete("eligible-degree-subject")
+ end
+ end
+ end
+
def self.start_page_url
Rails.application.routes.url_helpers.landing_page_path("additional-payments")
end
@@ -190,21 +208,6 @@ def replace_ecp_only_induction_not_completed_slugs(sequence)
sequence.replace(slugs)
end
- # This method swaps out the entire slug sequence and replaces it with this tiny
- # journey.
- def trainee_teacher_slugs(sequence)
- trainee_slugs = %w[
- current-school
- nqt-in-academic-year-after-itt
- eligible-itt-subject
- eligible-degree-subject
- future-eligibility
- ineligible
- ]
-
- [sequence.dup - trainee_slugs].flatten.each { |slug| sequence.delete(slug) }
- end
-
def induction_question_required?
# Induction question is not required if an ECP-eligible school is not selected.
return false unless ecp_school_selected?
diff --git a/app/models/journeys/eligibility_checker.rb b/app/models/journeys/eligibility_checker.rb
index 7e5b8efc59..1d81576813 100644
--- a/app/models/journeys/eligibility_checker.rb
+++ b/app/models/journeys/eligibility_checker.rb
@@ -63,6 +63,14 @@ def policies_eligible_now_and_sorted
policies_eligible_now_with_award_amount_and_sorted.map { |policy_with_award_amount| policy_with_award_amount.policy }
end
+ def potentially_still_eligible
+ policies.select do |policy|
+ policy::PolicyEligibilityChecker.new(
+ answers: @journey_session.answers
+ ).status != :ineligible
+ end
+ end
+
private
def policies_eligible_now_with_award_amount
diff --git a/app/models/journeys/page_sequence.rb b/app/models/journeys/page_sequence.rb
index 3bd345d712..6d1a85feee 100644
--- a/app/models/journeys/page_sequence.rb
+++ b/app/models/journeys/page_sequence.rb
@@ -20,10 +20,6 @@ def slugs
end
def next_slug
- if lup_policy_and_trainee_teacher_at_lup_school?
- return handle_trainee_teacher
- end
-
return "ineligible" if journey_ineligible?
if claim_submittable?
@@ -87,37 +83,6 @@ def can_skip_next_slug?
true if current_slug == "select-home-address" && answers.postcode.present?
end
- def lup_policy_and_trainee_teacher_at_lup_school?
- journey == Journeys::AdditionalPaymentsForTeaching && lup_teacher_at_lup_school
- end
-
- def lup_teacher_at_lup_school
- answers.nqt_in_academic_year_after_itt == false && Policies::LevellingUpPremiumPayments::SchoolEligibility.new(answers.current_school).eligible?
- end
-
- def handle_trainee_teacher
- case current_slug
- when "nqt-in-academic-year-after-itt"
- if answers.nqt_in_academic_year_after_itt?
- "supply-teacher"
- else
- @journey_session.answers.policy_year.in?(EligibilityCheckable::COMBINED_ECP_AND_LUP_POLICY_YEARS_BEFORE_FINAL_YEAR) ? "eligible-itt-subject" : "ineligible"
- end
- when "eligible-itt-subject"
- if answers.eligible_itt_subject.to_sym.in? JourneySubjectEligibilityChecker.fixed_lup_subject_symbols
- "future-eligibility"
- else
- "eligible-degree-subject"
- end
- when "eligible-degree-subject"
- if @journey_session.answers.eligible_degree_subject?
- "future-eligibility"
- else
- "ineligible"
- end
- end
- end
-
def current_slug_index
slugs.index(current_slug) || 0
end
diff --git a/app/models/policies/early_career_payments.rb b/app/models/policies/early_career_payments.rb
index 203b3475e4..bc5f165769 100644
--- a/app/models/policies/early_career_payments.rb
+++ b/app/models/policies/early_career_payments.rb
@@ -109,5 +109,73 @@ def payment_and_deductions_info_url
def auto_check_student_loan_plan_task?
true
end
+
+ def current_subject_symbols(claim_year:, itt_year:)
+ subject_symbols(claim_year: claim_year, itt_year: itt_year)
+ end
+
+ def future_subject_symbols(claim_year:, itt_year:)
+ future_years(claim_year).flat_map do |year|
+ subject_symbols(claim_year: year, itt_year: itt_year)
+ end
+ end
+
+ def current_and_future_subject_symbols(claim_year:, itt_year:)
+ [
+ *current_subject_symbols(
+ claim_year: claim_year,
+ itt_year: itt_year
+ ),
+ *future_subject_symbols(
+ claim_year: claim_year,
+ itt_year: itt_year
+ )
+ ].uniq
+ end
+
+ def subject_symbols(claim_year:, itt_year:)
+ case AcademicYear.wrap(claim_year)
+ when AcademicYear.new(2022), AcademicYear.new(2024)
+ case AcademicYear.wrap(itt_year)
+ when AcademicYear.new(2019)
+ [:mathematics]
+ when AcademicYear.new(2020)
+ [:chemistry, :foreign_languages, :mathematics, :physics]
+ else
+ []
+ end
+ when AcademicYear.new(2023)
+ case AcademicYear.wrap(itt_year)
+ when AcademicYear.new(2018)
+ [:mathematics]
+ when AcademicYear.new(2020)
+ [:chemistry, :foreign_languages, :mathematics, :physics]
+ else
+ []
+ end
+ else
+ []
+ end
+ end
+
+ def current_and_future_years(year)
+ fail "year before policy start year" if year < POLICY_START_YEAR
+
+ [year] + future_years(year)
+ end
+
+ def future_years(year)
+ fail "year before policy start year" if year < POLICY_START_YEAR
+
+ year + 1..POLICY_END_YEAR
+ end
+
+ def selectable_itt_years_for_claim_year(claim_year)
+ (AcademicYear.new(claim_year - 5)...AcademicYear.new(claim_year)).to_a
+ end
+
+ def closed?(claim_year)
+ claim_year > POLICY_END_YEAR
+ end
end
end
diff --git a/app/models/policies/early_career_payments/dqt_record.rb b/app/models/policies/early_career_payments/dqt_record.rb
index 24432f5cea..4f7b7dbd24 100644
--- a/app/models/policies/early_career_payments/dqt_record.rb
+++ b/app/models/policies/early_career_payments/dqt_record.rb
@@ -49,10 +49,11 @@ def eligible_itt_subject_for_claim
return :none_of_the_above if itt_subject_groups.empty? || !year
- itt_subject_checker = JourneySubjectEligibilityChecker.new(claim_year: current_academic_year, itt_year: year)
-
itt_subject_groups.delete_if do |itt_subject_group|
- !itt_subject_group.in?(itt_subject_checker.current_and_future_subject_symbols(EarlyCareerPayments))
+ EarlyCareerPayments.current_and_future_subject_symbols(
+ claim_year: current_academic_year,
+ itt_year: year
+ ).exclude?(itt_subject_group)
end.first.to_sym
rescue # JourneySubjectEligibilityChecker can also raise an exception if itt_year is out of eligible range
:none_of_the_above
@@ -62,7 +63,7 @@ def itt_academic_year_for_claim
return nil unless academic_date
year = AcademicYear.for(academic_date)
- eligible_years = JourneySubjectEligibilityChecker.selectable_itt_years_for_claim_year(current_academic_year)
+ eligible_years = EarlyCareerPayments.selectable_itt_years_for_claim_year(current_academic_year)
eligible_years.include?(year) ? year : AcademicYear.new
end
diff --git a/app/models/policies/early_career_payments/eligibility.rb b/app/models/policies/early_career_payments/eligibility.rb
index 43e768c20d..eb182254de 100644
--- a/app/models/policies/early_career_payments/eligibility.rb
+++ b/app/models/policies/early_career_payments/eligibility.rb
@@ -34,7 +34,7 @@ def policy
hsh[year] = AcademicYear::Type.new.serialize(year)
end.merge({AcademicYear.new => AcademicYear::Type.new.serialize(AcademicYear.new)})
- enum :itt_academic_year, ITT_ACADEMIC_YEARS
+ enum :itt_academic_year, ITT_ACADEMIC_YEARS, validate: true
enum :qualification, {
postgraduate_itt: 0,
diff --git a/app/models/policies/early_career_payments/policy_eligibility_checker.rb b/app/models/policies/early_career_payments/policy_eligibility_checker.rb
index d634e75ffb..30ba961afc 100644
--- a/app/models/policies/early_career_payments/policy_eligibility_checker.rb
+++ b/app/models/policies/early_career_payments/policy_eligibility_checker.rb
@@ -1,7 +1,6 @@
module Policies
module EarlyCareerPayments
class PolicyEligibilityChecker
- include Eligible
include EligibilityCheckable
attr_reader :answers
@@ -11,6 +10,102 @@ class PolicyEligibilityChecker
def initialize(answers:)
@answers = answers
end
+
+ def policy
+ Policies::EarlyCareerPayments
+ end
+
+ def induction_not_completed?
+ !induction_completed.nil? && !induction_completed?
+ end
+
+ def ecp_only_school?
+ Policies::EarlyCareerPayments::SchoolEligibility.new(current_school).eligible? &&
+ !Policies::LevellingUpPremiumPayments::SchoolEligibility.new(current_school).eligible?
+ end
+
+ def calculate_award_amount
+ return 0 if eligible_itt_subject.blank?
+
+ args = {policy_year: claim_year, itt_year: itt_academic_year, subject_symbol: eligible_itt_subject.to_sym, school: current_school}
+
+ if args.values.any?(&:blank?)
+ 0
+ else
+ Policies::EarlyCareerPayments::AwardAmountCalculator.new(**args).amount_in_pounds
+ end
+ end
+
+ private
+
+ def specific_eligible_now_attributes?
+ induction_completed? && itt_subject_eligible_now?
+ end
+
+ def itt_subject_eligible_now?
+ itt_subject = eligible_itt_subject # attribute name implies eligibility which isn't always the case
+ return false if itt_subject.blank?
+ return false if itt_subject_none_of_the_above?
+
+ EarlyCareerPayments.current_subject_symbols(
+ claim_year: claim_year,
+ itt_year: itt_academic_year
+ ).include?(itt_subject.to_sym)
+ end
+
+ def specific_ineligible_attributes?
+ 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?
+ itt_subject = eligible_itt_subject # attribute name implies eligibility which isn't always the case
+ return false if itt_subject.blank?
+ return true if itt_subject_none_of_the_above?
+
+ EarlyCareerPayments.current_and_future_subject_symbols(
+ claim_year: claim_year,
+ itt_year: itt_academic_year
+ ).exclude?(itt_subject.to_sym)
+ end
+
+ def specific_eligible_later_attributes?
+ newly_qualified_teacher? && ((induction_not_completed? && any_future_policy_years?) || (!itt_subject_eligible_now? && itt_subject_eligible_later?))
+ end
+
+ def itt_subject_eligible_later?
+ itt_subject = eligible_itt_subject # attribute name implies eligibility which isn't always the case
+ return false if itt_subject.blank?
+ return false if itt_subject_none_of_the_above?
+
+ EarlyCareerPayments.future_subject_symbols(
+ claim_year: claim_year,
+ itt_year: itt_academic_year
+ ).include?(itt_subject.to_sym)
+ end
+
+ # TODO: Is this used anywhere?
+ def itt_subject_ineligible?
+ return false if claim_year.blank?
+
+ itt_subject_other_than_those_eligible_now_or_in_the_future?
+ end
+
+ def itt_subject_other_than_those_eligible_now_or_in_the_future?
+ itt_subject = eligible_itt_subject # attribute name implies eligibility which isn't always the case
+ return false if itt_subject.blank?
+
+ args = {claim_year: claim_year, itt_year: itt_academic_year}
+
+ if args.any?(&:blank?)
+ # can still rule some out
+ itt_subject_none_of_the_above?
+ else
+ EarlyCareerPayments.current_and_future_subject_symbols(
+ claim_year: claim_year,
+ itt_year: itt_academic_year
+ ).exclude?(itt_subject_symbol)
+ end
+ end
end
end
end
diff --git a/app/models/policies/levelling_up_premium_payments.rb b/app/models/policies/levelling_up_premium_payments.rb
index 6926875a2f..e2a41761a7 100644
--- a/app/models/policies/levelling_up_premium_payments.rb
+++ b/app/models/policies/levelling_up_premium_payments.rb
@@ -27,7 +27,8 @@ module LevellingUpPremiumPayments
SEARCHABLE_ELIGIBILITY_ATTRIBUTES = %w[teacher_reference_number].freeze
POLICY_START_YEAR = AcademicYear.new(2022).freeze
- POLICY_END_YEAR = AcademicYear.new(2024).freeze
+ POLICY_END_YEAR = AcademicYear.new(2025).freeze
+ POLICY_RANGE = POLICY_START_YEAR..POLICY_END_YEAR
# Percentage of claims to QA
MIN_QA_THRESHOLD = 10
@@ -99,5 +100,67 @@ def payroll_file_name
def auto_check_student_loan_plan_task?
true
end
+
+ def current_subject_symbols(claim_year:, itt_year:)
+ subject_symbols(claim_year: claim_year, itt_year: itt_year)
+ end
+
+ def future_subject_symbols(claim_year:, itt_year:)
+ future_years(claim_year).flat_map do |year|
+ subject_symbols(claim_year: year, itt_year: itt_year)
+ end
+ end
+
+ def current_and_future_subject_symbols(claim_year:, itt_year:)
+ [
+ *current_subject_symbols(
+ claim_year: claim_year,
+ itt_year: itt_year
+ ),
+ *future_subject_symbols(
+ claim_year: claim_year,
+ itt_year: itt_year
+ )
+ ].uniq
+ end
+
+ # Ideally we wouldn't have this method at all. Unfortunately it was hardcoded like
+ # this before we realised trainee teachers weren't as special a case as we
+ # thought.
+ def fixed_subject_symbols
+ [:chemistry, :computing, :mathematics, :physics]
+ end
+
+ def subject_symbols(claim_year:, itt_year:)
+ return [] unless POLICY_RANGE.cover?(claim_year)
+
+ previous_five_years = (claim_year - 5)...claim_year
+
+ if previous_five_years.cover?(itt_year)
+ fixed_subject_symbols
+ else
+ []
+ end
+ end
+
+ def current_and_future_years(year)
+ fail "year before policy start year" if year < POLICY_START_YEAR
+
+ [year] + future_years(year)
+ end
+
+ def future_years(year)
+ fail "year before policy start year" if year < POLICY_START_YEAR
+
+ year + 1..POLICY_END_YEAR
+ end
+
+ def selectable_itt_years_for_claim_year(claim_year)
+ (AcademicYear.new(claim_year - 5)...AcademicYear.new(claim_year)).to_a
+ end
+
+ def closed?(claim_year)
+ claim_year > POLICY_END_YEAR
+ end
end
end
diff --git a/app/models/policies/levelling_up_premium_payments/dqt_record.rb b/app/models/policies/levelling_up_premium_payments/dqt_record.rb
index 5146d94889..235f2e85f9 100644
--- a/app/models/policies/levelling_up_premium_payments/dqt_record.rb
+++ b/app/models/policies/levelling_up_premium_payments/dqt_record.rb
@@ -1,5 +1,3 @@
-require "journey_subject_eligibility_checker"
-
module Policies
module LevellingUpPremiumPayments
class DqtRecord
@@ -110,7 +108,7 @@ def no_invalid_subject_codes?
end
def itt_year_within_allowed_range?(year = itt_year)
- eligible_itt_years = JourneySubjectEligibilityChecker.selectable_itt_years_for_claim_year(current_academic_year)
+ eligible_itt_years = LevellingUpPremiumPayments.selectable_itt_years_for_claim_year(current_academic_year)
eligible_itt_years.include?(year)
end
end
diff --git a/app/models/policies/levelling_up_premium_payments/policy_eligibility_checker.rb b/app/models/policies/levelling_up_premium_payments/policy_eligibility_checker.rb
index 353173af08..9eb213964a 100644
--- a/app/models/policies/levelling_up_premium_payments/policy_eligibility_checker.rb
+++ b/app/models/policies/levelling_up_premium_payments/policy_eligibility_checker.rb
@@ -1,7 +1,6 @@
module Policies
module LevellingUpPremiumPayments
class PolicyEligibilityChecker
- include Eligible
include EligibilityCheckable
attr_reader :answers
@@ -11,6 +10,84 @@ class PolicyEligibilityChecker
def initialize(answers:)
@answers = answers
end
+
+ def policy
+ Policies::LevellingUpPremiumPayments
+ end
+
+ def indicated_ineligible_itt_subject?
+ return false if eligible_itt_subject.blank?
+
+ if claim_year.blank? || itt_academic_year.blank?
+ # trainee teacher who won't have given their ITT year
+ eligible_itt_subject.present? && LevellingUpPremiumPayments.fixed_subject_symbols.exclude?(eligible_itt_subject.to_sym)
+ else
+ LevellingUpPremiumPayments.subject_symbols(
+ claim_year: claim_year,
+ itt_year: itt_academic_year
+ ).exclude?(eligible_itt_subject.to_sym)
+ end
+ end
+
+ def calculate_award_amount
+ premium_payment_award&.award_amount
+ end
+
+ private
+
+ def premium_payment_award
+ return unless current_school.present?
+
+ current_school.levelling_up_premium_payments_awards.find_by(
+ academic_year: claim_year.to_s
+ )
+ end
+
+ def indicated_ecp_only_itt_subject?
+ eligible_itt_subject.present? && (eligible_itt_subject.to_sym == :foreign_languages)
+ end
+
+ def specific_eligible_now_attributes?
+ eligible_itt_subject_or_relevant_degree?
+ end
+
+ def eligible_itt_subject_or_relevant_degree?
+ good_itt_subject? || eligible_degree?
+ end
+
+ def good_itt_subject?
+ return false if eligible_itt_subject.blank?
+
+ if claim_year.blank? || itt_academic_year.blank?
+ # trainee teacher who won't have given their ITT year
+ eligible_itt_subject.present? && eligible_itt_subject.to_sym.in?(Policies::LevellingUpPremiumPayments.fixed_subject_symbols)
+ else
+ LevellingUpPremiumPayments.current_subject_symbols(
+ claim_year: claim_year,
+ itt_year: itt_academic_year
+ ).include?(eligible_itt_subject.to_sym)
+ end
+ end
+
+ def eligible_degree?
+ eligible_degree_subject?
+ end
+
+ def specific_ineligible_attributes?
+ indicated_ecp_only_itt_subject? || ineligible_itt_subject_and_no_relevant_degree?
+ end
+
+ def ineligible_itt_subject_and_no_relevant_degree?
+ indicated_ineligible_itt_subject? && lacks_eligible_degree?
+ end
+
+ def specific_eligible_later_attributes?
+ trainee_teacher? && eligible_itt_subject_or_relevant_degree?
+ end
+
+ def lacks_eligible_degree?
+ eligible_degree_subject == false
+ end
end
end
end
diff --git a/app/views/additional_payments/claims/_ineligibility_ecp_only_ecp_closed.html.erb b/app/views/additional_payments/claims/_ineligibility_ecp_only_ecp_closed.html.erb
new file mode 100644
index 0000000000..7931af3f8b
--- /dev/null
+++ b/app/views/additional_payments/claims/_ineligibility_ecp_only_ecp_closed.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 the policy has now closed.
+
+
+ You are not eligible for the
+ <%= link_to("#{I18n.t("levelling_up_premium_payments.policy_short_name").downcase} (opens in new tab)", Policies::LevellingUpPremiumPayments.eligibility_criteria_url, class: "govuk-link", target: "_blank") %>
+ because the school you teach in is not eligible. <%= I18n.t("levelling_up_premium_payments.policy_short_name").capitalize.pluralize %> 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(I18n.t("levelling_up_premium_payments.policy_short_name").downcase.pluralize, Policies::LevellingUpPremiumPayments.eligibility_criteria_url, class: "govuk-link") %>.
+
diff --git a/app/views/additional_payments/claims/eligible_degree_subject.html.erb b/app/views/additional_payments/claims/eligible_degree_subject.html.erb
index bae29a44c3..1a292e2ff3 100644
--- a/app/views/additional_payments/claims/eligible_degree_subject.html.erb
+++ b/app/views/additional_payments/claims/eligible_degree_subject.html.erb
@@ -18,7 +18,7 @@
This can be an undergraduate or postgraduate degree in
- <%= JourneySubjectEligibilityChecker.fixed_lup_subject_symbols.to_sentence(last_word_connector: ' or ') %>.
+ <%= Policies::LevellingUpPremiumPayments.fixed_subject_symbols.to_sentence(last_word_connector: ' or ') %>.
<%= errors_tag f.object, :eligible_degree_subject %>
diff --git a/lib/ineligibility_reason_checker.rb b/lib/ineligibility_reason_checker.rb
index 8362bbf821..e2889067e1 100644
--- a/lib/ineligibility_reason_checker.rb
+++ b/lib/ineligibility_reason_checker.rb
@@ -4,7 +4,9 @@ def initialize(answers)
end
def reason
- if current_school?
+ if ecp_only_and_ecp_closed?
+ :ecp_only_ecp_closed
+ elsif current_school?
:current_school
elsif dqt_data_ineligible?
:dqt_data_ineligible
@@ -41,6 +43,15 @@ def reason
private
+ def ecp_only_and_ecp_closed?
+ school = @answers.current_school
+
+ [
+ Policies::EarlyCareerPayments::SchoolEligibility.new(school).eligible?,
+ !Policies::LevellingUpPremiumPayments::SchoolEligibility.new(school).eligible?
+ ].all? && Policies::EarlyCareerPayments.closed?(@answers.policy_year)
+ end
+
def current_school?
school = @answers.current_school
@@ -154,10 +165,10 @@ def subject_invalid_for_ecp?
end
def ecp_subject_options
- JourneySubjectEligibilityChecker.new(
+ Policies::EarlyCareerPayments.current_and_future_subject_symbols(
claim_year: @answers.policy_year,
itt_year: @answers.itt_academic_year
- ).current_and_future_subject_symbols(Policies::EarlyCareerPayments)
+ )
end
def bad_itt_year_for_ecp?
diff --git a/lib/journey_subject_eligibility_checker.rb b/lib/journey_subject_eligibility_checker.rb
deleted file mode 100644
index e1f527a33d..0000000000
--- a/lib/journey_subject_eligibility_checker.rb
+++ /dev/null
@@ -1,170 +0,0 @@
-# TODO: Move this into an additional-payments journey specific namespace
-#
-class JourneySubjectEligibilityChecker
- def initialize(claim_year:, itt_year:)
- raise "Claim year #{claim_year} is after ECP and LUP both ended" if claim_year > EligibilityCheckable::FINAL_COMBINED_ECP_AND_LUP_POLICY_YEAR
-
- @claim_year = claim_year
-
- validate_itt_year(itt_year)
- @itt_year = itt_year
- end
-
- def future_claim_years
- if none_of_the_above_or_blank?(@itt_year)
- []
- else
- ((@claim_year + 1)..EligibilityCheckable::FINAL_COMBINED_ECP_AND_LUP_POLICY_YEAR).to_a
- end
- end
-
- def selectable_itt_years
- JourneySubjectEligibilityChecker.selectable_itt_years_for_claim_year(@claim_year)
- end
-
- def self.selectable_subject_symbols(answers)
- if answers.nqt_in_academic_year_after_itt
- new(
- claim_year: answers.policy_year,
- itt_year: answers.itt_academic_year
- ).selectable_subject_symbols(answers)
- elsif answers.policy_year.in?(EligibilityCheckable::COMBINED_ECP_AND_LUP_POLICY_YEARS_BEFORE_FINAL_YEAR)
- # they get the standard, unchanging LUP subject set because they won't have qualified in time for ECP by 2022/2023
- # and they won't have given an ITT year
- fixed_lup_subject_symbols
- else
- []
- end.sort
- end
-
- def self.selectable_itt_years_for_claim_year(claim_year)
- (AcademicYear.new(claim_year - 5)...AcademicYear.new(claim_year)).to_a
- end
-
- def self.current_and_future_subject_symbols(answers)
- return [] if answers.itt_academic_year.blank?
-
- if answers.nqt_in_academic_year_after_itt
- JourneySubjectEligibilityChecker.new(claim_year: answers.policy_year, itt_year: answers.itt_academic_year).current_and_future_subject_symbols(answers.policy)
- elsif answers.policy_year.in?(EligibilityCheckable::COMBINED_ECP_AND_LUP_POLICY_YEARS_BEFORE_FINAL_YEAR)
- # they get the standard, unchanging LUP subject set because they won't have qualified in time for ECP by 2022/2023
- # and they won't have given an ITT year
- JourneySubjectEligibilityChecker.fixed_lup_subject_symbols
- else
- []
- end.sort
- end
-
- # Ideally we wouldn't have this method at all. Unfortunately it was hardcoded like
- # this before we realised trainee teachers weren't as special a case as we
- # thought.
- def self.fixed_lup_subject_symbols
- [:chemistry, :computing, :mathematics, :physics]
- end
-
- # NOTE: ONLY used by specs
- def self.first_eligible_itt_year_for_subject(policy:, claim_year:, subject_symbol:)
- raise "[#{subject_symbol}] is not a symbol" unless subject_symbol.is_a?(Symbol)
- itt_years = JourneySubjectEligibilityChecker.selectable_itt_years_for_claim_year(claim_year)
-
- itt_years.detect do |itt_year|
- checker = JourneySubjectEligibilityChecker.new(claim_year: claim_year, itt_year: itt_year)
- subject_symbol.in?(checker.current_subject_symbols(policy))
- end
- end
-
- def current_and_future_subject_symbols(policy)
- (current_subject_symbols(policy) + future_subject_symbols(policy)).uniq
- end
-
- def current_subject_symbols(policy)
- if none_of_the_above_or_blank?(@itt_year)
- []
- else
- subject_symbols(policy: policy, claim_year: @claim_year, itt_year: @itt_year)
- end
- end
-
- def future_subject_symbols(policy)
- if none_of_the_above_or_blank?(@itt_year)
- []
- else
- future_claim_years.collect { |future_year| subject_symbols(policy: policy, claim_year: future_year, itt_year: @itt_year) }.flatten.uniq
- end
- end
-
- def selectable_subject_symbols(answers)
- return [] if answers.itt_academic_year.blank?
-
- potentially_still_eligible_policies(answers).map do |policy|
- current_and_future_subject_symbols(policy)
- end.flatten.uniq
- end
-
- private
-
- def potentially_still_eligible_policies(answers)
- Journeys::AdditionalPaymentsForTeaching::POLICIES.select do |policy|
- policy::PolicyEligibilityChecker.new(answers: answers).status != :ineligible
- end
- end
-
- def validate_itt_year(itt_year)
- unless none_of_the_above_or_blank?(itt_year)
- raise "ITT year #{itt_year} is outside the window for claim year #{@claim_year}" unless itt_year.in?(selectable_itt_years)
- end
- end
-
- def none_of_the_above_or_blank?(itt_year)
- itt_year.blank? || none_of_the_above?(itt_year)
- end
-
- def none_of_the_above?(itt_year)
- itt_year.in? [AcademicYear.new, "None"]
- end
-
- def subject_symbols(policy:, claim_year:, itt_year:)
- raise "Unsupported policy: #{policy}" unless policy.in?(Journeys::AdditionalPaymentsForTeaching::POLICIES)
-
- case policy
- when Policies::EarlyCareerPayments
- year = claim_year.is_a?(AcademicYear) ? claim_year : AcademicYear.new(claim_year)
- case year
- when AcademicYear.new(2022), AcademicYear.new(2024)
- case itt_year
- when AcademicYear.new(2019)
- [:mathematics]
- when AcademicYear.new(2020)
- [:chemistry, :foreign_languages, :mathematics, :physics]
- else
- []
- end
- when AcademicYear.new(2023)
- case itt_year
- when AcademicYear.new(2018)
- [:mathematics]
- when AcademicYear.new(2020)
- [:chemistry, :foreign_languages, :mathematics, :physics]
- else
- []
- end
- else
- []
- end
- when Policies::LevellingUpPremiumPayments
- case claim_year
- when EligibilityCheckable::COMBINED_ECP_AND_LUP_POLICY_YEARS
- year = itt_year.is_a?(AcademicYear) ? itt_year : AcademicYear.new(itt_year)
-
- case year
- when (claim_year - 5)...claim_year
- [:chemistry, :computing, :mathematics, :physics]
- else
- []
- end
- else
- []
- end
- end
- end
-end
diff --git a/spec/factories/policies/early_career_payments/eligibilities.rb b/spec/factories/policies/early_career_payments/eligibilities.rb
index dfcccd38df..f23e0b12cf 100644
--- a/spec/factories/policies/early_career_payments/eligibilities.rb
+++ b/spec/factories/policies/early_career_payments/eligibilities.rb
@@ -2,6 +2,10 @@
factory :early_career_payments_eligibility, class: "Policies::EarlyCareerPayments::Eligibility" do
award_amount { 5000.0 }
+ itt_academic_year do
+ Journeys.for_policy(Policies::EarlyCareerPayments).configuration.current_academic_year - 3
+ end
+
trait :eligible do
teacher_reference_number { generate(:teacher_reference_number) }
eligible_now
diff --git a/spec/features/admin/admin_claim_tasks_update_with_dqt_api_spec.rb b/spec/features/admin/admin_claim_tasks_update_with_dqt_api_spec.rb
index 77639b8b7f..8b1c18edc9 100644
--- a/spec/features/admin/admin_claim_tasks_update_with_dqt_api_spec.rb
+++ b/spec/features/admin/admin_claim_tasks_update_with_dqt_api_spec.rb
@@ -139,11 +139,22 @@ def task_outcome
end
let(:first_eligible_itt_academic_year) {
- JourneySubjectEligibilityChecker.first_eligible_itt_year_for_subject(
- policy: claim.eligibility.policy,
- claim_year: Journeys.for_policy(claim.eligibility.policy).configuration.current_academic_year,
- subject_symbol: claim.eligibility.eligible_itt_subject.to_sym
- )
+ subject_symbol = claim.eligibility.eligible_itt_subject.to_sym
+
+ policy = claim.eligibility.policy
+
+ claim_year = Journeys.for_policy(policy).configuration.current_academic_year
+
+ itt_years = policy.selectable_itt_years_for_claim_year(claim_year)
+
+ itt_years.detect do |itt_year|
+ subject_symbol.in?(
+ policy.current_subject_symbols(
+ claim_year: claim_year,
+ itt_year: itt_year
+ )
+ )
+ end
}
context "with EarlyCareerPayments policy" do
diff --git a/spec/features/combined_teacher_claim_journey_spec.rb b/spec/features/combined_teacher_claim_journey_spec.rb
index 42e6229cf1..53c08457d7 100644
--- a/spec/features/combined_teacher_claim_journey_spec.rb
+++ b/spec/features/combined_teacher_claim_journey_spec.rb
@@ -6,9 +6,9 @@
end
let(:eligibility) { claim.eligibility }
- before { create(:journey_configuration, :additional_payments, current_academic_year: AcademicYear.new(2023)) }
-
scenario "Eligible for both" do
+ create(:journey_configuration, :additional_payments, current_academic_year: AcademicYear.new(2023))
+
school = create(:school, :combined_journey_eligibile_for_all)
visit new_claim_path(Journeys::AdditionalPaymentsForTeaching::ROUTING_NAME)
@@ -243,6 +243,8 @@
end
scenario "Eligible for only one" do
+ create(:journey_configuration, :additional_payments, current_academic_year: AcademicYear.new(2023))
+
school = create(:school, :early_career_payments_uplifted)
visit new_claim_path(Journeys::AdditionalPaymentsForTeaching::ROUTING_NAME)
@@ -323,4 +325,84 @@
expect(page).not_to have_selector('input[type="radio"]')
expect(page).to have_button("Apply now")
end
+
+ context "when ECP is closed" do
+ before do
+ create(
+ :journey_configuration,
+ :additional_payments,
+ current_academic_year: AcademicYear.new(2025)
+ )
+ end
+
+ scenario "choosing an ecp only school is ineligible" do
+ school = create(:school, :early_career_payments_eligible)
+
+ visit new_claim_path(Journeys::AdditionalPaymentsForTeaching::ROUTING_NAME)
+
+ click_on "Continue without signing"
+
+ choose_school school
+
+ expect(page).to have_content "You are not eligible"
+ expect(page).to have_content "the policy has now closed"
+ end
+
+ scenario "choosing a lup eligible school allows completing the journey" do
+ school = create(:school, :combined_journey_eligibile_for_all)
+
+ visit new_claim_path(Journeys::AdditionalPaymentsForTeaching::ROUTING_NAME)
+
+ click_on "Continue without signing"
+
+ choose_school school
+ click_on "Continue"
+
+ # - Have you started your first year as a newly qualified teacher?
+ choose "Yes"
+ click_on "Continue"
+
+ # - Have you completed your induction as an early-career teacher?
+ choose "Yes"
+ click_on "Continue"
+
+ # - Are you currently employed as a supply teacher
+ choose "No"
+ click_on "Continue"
+
+ # - Poor performance
+ 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?
+ choose("Undergraduate initial teacher training (ITT)")
+ click_on "Continue"
+
+ # - In which academic year did you complete your undergraduate ITT?
+ choose("2024 to 2025")
+ click_on "Continue"
+
+ # - Which subject did you do your undergraduate ITT in
+ choose "Mathematics"
+ click_on "Continue"
+
+ # Do you spend at least half of your contracted hours teaching eligible
+ # subjects?
+ choose "Yes"
+ click_on "Continue"
+
+ # Check your answers
+ click_on "Continue"
+
+ expect(page).to have_content("You’re eligible for an additional payment")
+ expect(page).to have_content(
+ "you can apply for a school targeted retention incentive"
+ )
+ end
+ end
end
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 7614e4ddb2..0570495d19 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
@@ -6,7 +6,7 @@
let!(:journey_configuration) { create(:journey_configuration, :additional_payments) }
let!(:school) { create(:school, :combined_journey_eligibile_for_all) }
- let(:eligible_itt_years) { JourneySubjectEligibilityChecker.selectable_itt_years_for_claim_year(journey_configuration.current_academic_year) }
+ let(:eligible_itt_years) { Journeys::AdditionalPaymentsForTeaching.selectable_itt_years_for_claim_year(journey_configuration.current_academic_year) }
let(:academic_date) { Date.new(eligible_itt_years.first.start_year, 12, 1) }
let(:itt_year) { AcademicYear.for(academic_date) }
let(:trn) { 1234567 }
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 e916b675eb..32c040bd6e 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
@@ -7,7 +7,7 @@
let!(:journey_configuration) { create(:journey_configuration, :additional_payments, current_academic_year: AcademicYear.new(2023)) }
let!(:school) { create(:school, :combined_journey_eligibile_for_all) }
- let(:eligible_itt_years) { JourneySubjectEligibilityChecker.selectable_itt_years_for_claim_year(journey_configuration.current_academic_year) }
+ let(:eligible_itt_years) { Journeys::AdditionalPaymentsForTeaching.selectable_itt_years_for_claim_year(journey_configuration.current_academic_year) }
let(:academic_date) { Date.new(eligible_itt_years.first.start_year, 12, 1) }
let(:itt_year) { AcademicYear.for(academic_date) }
let(:trn) { 1234567 }
diff --git a/spec/features/ineligible_student_loans_claims_spec.rb b/spec/features/ineligible_student_loans_claims_spec.rb
index abe4dfa63e..a0641f4e36 100644
--- a/spec/features/ineligible_student_loans_claims_spec.rb
+++ b/spec/features/ineligible_student_loans_claims_spec.rb
@@ -9,7 +9,7 @@
let!(:ineligible_school) { create(:school, :student_loans_ineligible) }
let(:import_zero_amount_slc_data) { create(:student_loans_data, nino:, date_of_birth:, plan_type_of_deduction: 1, amount: 0) }
let(:import_no_data_slc_data) { create(:student_loans_data, nino:, date_of_birth:, plan_type_of_deduction: nil, amount: 0) }
- let(:eligible_itt_years) { JourneySubjectEligibilityChecker.selectable_itt_years_for_claim_year(journey_configuration.current_academic_year) }
+ let(:eligible_itt_years) { Journeys::AdditionalPaymentsForTeaching.selectable_itt_years_for_claim_year(journey_configuration.current_academic_year) }
let(:academic_date) { Date.new(eligible_itt_years.first.start_year, 12, 1) }
let(:itt_year) { AcademicYear.for(academic_date) }
let(:trn) { 1234567 }
diff --git a/spec/features/tslr/tslr_claim_journey_with_teacher_id_spec.rb b/spec/features/tslr/tslr_claim_journey_with_teacher_id_spec.rb
index fea19293ad..0b1fc8bbec 100644
--- a/spec/features/tslr/tslr_claim_journey_with_teacher_id_spec.rb
+++ b/spec/features/tslr/tslr_claim_journey_with_teacher_id_spec.rb
@@ -6,7 +6,7 @@
let!(:journey_configuration) { create(:journey_configuration, :student_loans) }
let!(:school) { create(:school, :student_loans_eligible) }
- let(:eligible_itt_years) { JourneySubjectEligibilityChecker.selectable_itt_years_for_claim_year(journey_configuration.current_academic_year) }
+ let(:eligible_itt_years) { Journeys::AdditionalPaymentsForTeaching.selectable_itt_years_for_claim_year(journey_configuration.current_academic_year) }
let(:academic_date) { Date.new(eligible_itt_years.first.start_year, 12, 1) }
let(:itt_year) { AcademicYear.for(academic_date) }
let(:trn) { 1234567 }
diff --git a/spec/forms/journeys/additional_payments_for_teaching/eligible_itt_subject_form_spec.rb b/spec/forms/journeys/additional_payments_for_teaching/eligible_itt_subject_form_spec.rb
index 01ae9565a3..b6792241c6 100644
--- a/spec/forms/journeys/additional_payments_for_teaching/eligible_itt_subject_form_spec.rb
+++ b/spec/forms/journeys/additional_payments_for_teaching/eligible_itt_subject_form_spec.rb
@@ -18,7 +18,10 @@
:additional_payments_answers,
trainee_teacher,
itt_academic_year: itt_academic_year,
- current_school_id: create(:school, :early_career_payments_eligible).id
+ current_school_id: create(
+ :school,
+ :early_career_payments_eligible
+ ).id
)
)
end
@@ -50,7 +53,7 @@
context "when single subject available" do
before do
- allow(JourneySubjectEligibilityChecker).to receive(:selectable_subject_symbols).and_return([:mathematics])
+ allow(Journeys::AdditionalPaymentsForTeaching).to receive(:selectable_subject_symbols).and_return([:mathematics])
end
let(:answers) do
@@ -160,8 +163,8 @@
context "when the subject list contains chemistry" do
before do
- allow(JourneySubjectEligibilityChecker).to(
- receive(:fixed_lup_subject_symbols).and_return([:chemistry])
+ allow(Policies::LevellingUpPremiumPayments).to(
+ receive(:fixed_subject_symbols).and_return([:chemistry])
)
end
@@ -170,8 +173,8 @@
context "when the subject list contains physics" do
before do
- allow(JourneySubjectEligibilityChecker).to(
- receive(:fixed_lup_subject_symbols).and_return([:physics])
+ allow(Policies::LevellingUpPremiumPayments).to(
+ receive(:fixed_subject_symbols).and_return([:physics])
)
end
@@ -180,8 +183,8 @@
context "when the subject list does not contain chemistry or physics" do
before do
- allow(JourneySubjectEligibilityChecker).to(
- receive(:fixed_lup_subject_symbols).and_return([:mathematics])
+ allow(Policies::LevellingUpPremiumPayments).to(
+ receive(:fixed_subject_symbols).and_return([:mathematics])
)
end
diff --git a/spec/helpers/claims/itt_subject_helper_spec.rb b/spec/helpers/claims/itt_subject_helper_spec.rb
index 77ac2364c0..3c1c4b4ff3 100644
--- a/spec/helpers/claims/itt_subject_helper_spec.rb
+++ b/spec/helpers/claims/itt_subject_helper_spec.rb
@@ -94,7 +94,8 @@
build(
:additional_payments_answers,
:lup_ineligible,
- :ecp_eligible_later
+ :ecp_eligible_later,
+ itt_academic_year: AcademicYear.new(2020)
)
end
diff --git a/spec/helpers/early_career_payments_helper_spec.rb b/spec/helpers/early_career_payments_helper_spec.rb
index df975b10eb..7a02816854 100644
--- a/spec/helpers/early_career_payments_helper_spec.rb
+++ b/spec/helpers/early_career_payments_helper_spec.rb
@@ -29,7 +29,7 @@
subject do
helper.eligible_itt_subject_translation(
journey_session.answers,
- JourneySubjectEligibilityChecker.selectable_subject_symbols(journey_session.answers)
+ Journeys::AdditionalPaymentsForTeaching.selectable_subject_symbols(journey_session)
)
end
diff --git a/spec/lib/ineligibility_reason_checker_spec.rb b/spec/lib/ineligibility_reason_checker_spec.rb
index d2c19ada0a..4547608848 100644
--- a/spec/lib/ineligibility_reason_checker_spec.rb
+++ b/spec/lib/ineligibility_reason_checker_spec.rb
@@ -278,7 +278,7 @@
:additional_payments_answers,
:ecp_and_lup_eligible,
:trainee_teacher,
- academic_year: AcademicYear.new(2024),
+ academic_year: AcademicYear.new(2025),
current_school_id: school.id
)
end
diff --git a/spec/lib/journey_subject_eligibility_checker_spec.rb b/spec/lib/journey_subject_eligibility_checker_spec.rb
deleted file mode 100644
index ca4f792b69..0000000000
--- a/spec/lib/journey_subject_eligibility_checker_spec.rb
+++ /dev/null
@@ -1,1188 +0,0 @@
-require "rails_helper"
-require "journey_subject_eligibility_checker"
-
-RSpec.describe JourneySubjectEligibilityChecker do
- describe ".new" do
- context "claim year validation" do
- context "after LUP and ECP" do
- specify { expect { described_class.new(claim_year: AcademicYear.new(2025), itt_year: AcademicYear.new(2024)) }.to raise_error("Claim year 2025/2026 is after ECP and LUP both ended") }
- end
- end
-
- context "ITT year validation" do
- context "inside window" do
- specify { expect { described_class.new(claim_year: AcademicYear.new(2022), itt_year: AcademicYear.new(2017)) }.not_to raise_error }
- end
-
- context "outside window" do
- specify { expect { described_class.new(claim_year: AcademicYear.new(2022), itt_year: AcademicYear.new(2016)) }.to raise_error("ITT year 2016/2017 is outside the window for claim year 2022/2023") }
- end
-
- context "None of the above" do
- specify { expect { described_class.new(claim_year: AcademicYear.new(2022), itt_year: AcademicYear.new) }.not_to raise_error }
- end
- end
- end
-
- describe "#future_claim_years" do
- context "2022/2023 claim year" do
- subject { described_class.new(claim_year: AcademicYear.new(2022), itt_year: AcademicYear.new(2021)) }
-
- specify { expect(subject.future_claim_years).to contain_exactly(AcademicYear.new(2023), AcademicYear.new(2024)) }
- end
-
- context "2023/2024 claim year" do
- subject { described_class.new(claim_year: AcademicYear.new(2023), itt_year: AcademicYear.new(2022)) }
-
- specify { expect(subject.future_claim_years).to contain_exactly(AcademicYear.new(2024)) }
- end
-
- context "2024/2025 claim year" do
- subject { described_class.new(claim_year: AcademicYear.new(2024), itt_year: AcademicYear.new(2023)) }
-
- specify { expect(subject.future_claim_years).to be_empty }
- end
-
- context "None of the above ITT year" do
- subject { described_class.new(claim_year: AcademicYear.new(2022), itt_year: AcademicYear.new) }
-
- specify { expect(subject.future_claim_years).to be_empty }
- end
- end
-
- describe "#selectable_itt_years" do
- context "2022/2023 claim year" do
- subject { described_class.new(claim_year: AcademicYear.new(2022), itt_year: AcademicYear.new(2021)).selectable_itt_years }
-
- it { is_expected.to contain_exactly(AcademicYear.new(2017), AcademicYear.new(2018), AcademicYear.new(2019), AcademicYear.new(2020), AcademicYear.new(2021)) }
- end
-
- context "2023/2024 claim year" do
- subject { described_class.new(claim_year: AcademicYear.new(2023), itt_year: AcademicYear.new(2022)).selectable_itt_years }
-
- it { is_expected.to contain_exactly(AcademicYear.new(2018), AcademicYear.new(2019), AcademicYear.new(2020), AcademicYear.new(2021), AcademicYear.new(2022)) }
- end
-
- context "2024/2025 claim year" do
- subject { described_class.new(claim_year: AcademicYear.new(2024), itt_year: AcademicYear.new(2023)).selectable_itt_years }
-
- it { is_expected.to contain_exactly(AcademicYear.new(2019), AcademicYear.new(2020), AcademicYear.new(2021), AcademicYear.new(2022), AcademicYear.new(2023)) }
- end
- end
-
- describe ".selectable_itt_years_for_view" do
- context "2022/2023 claim year" do
- subject { described_class.selectable_itt_years_for_claim_year(AcademicYear.new(2022)) }
-
- it { is_expected.to eq([AcademicYear.new(2017), AcademicYear.new(2018), AcademicYear.new(2019), AcademicYear.new(2020), AcademicYear.new(2021)]) }
- end
-
- context "2023/2024 claim year" do
- subject { described_class.selectable_itt_years_for_claim_year(AcademicYear.new(2023)) }
-
- it { is_expected.to eq([AcademicYear.new(2018), AcademicYear.new(2019), AcademicYear.new(2020), AcademicYear.new(2021), AcademicYear.new(2022)]) }
- end
-
- context "2024/2025 claim year" do
- subject { described_class.selectable_itt_years_for_claim_year(AcademicYear.new(2024)) }
-
- it { is_expected.to eq([AcademicYear.new(2019), AcademicYear.new(2020), AcademicYear.new(2021), AcademicYear.new(2022), AcademicYear.new(2023)]) }
- end
- end
-
- describe "#current_subject_symbols" do
- subject { described_class.new(claim_year: claim_year, itt_year: itt_year).current_subject_symbols(policy) }
-
- context "ECP" do
- let(:policy) { Policies::EarlyCareerPayments }
-
- context "2022 claim year" do
- let(:claim_year) { AcademicYear.new(2022) }
-
- context "None of the above ITT year" do
- let(:itt_year) { AcademicYear.new }
-
- it { is_expected.to be_empty }
- end
-
- context "2017 ITT year" do
- let(:itt_year) { AcademicYear.new(2017) }
-
- it { is_expected.to be_empty }
- end
-
- context "2018 ITT year" do
- let(:itt_year) { AcademicYear.new(2018) }
-
- it { is_expected.to be_empty }
- end
-
- context "2019 ITT year" do
- let(:itt_year) { AcademicYear.new(2019) }
-
- it { is_expected.to contain_exactly(:mathematics) }
- end
-
- context "2020 ITT year" do
- let(:itt_year) { AcademicYear.new(2020) }
-
- it { is_expected.to contain_exactly(:chemistry, :foreign_languages, :mathematics, :physics) }
- end
-
- context "2021 ITT year" do
- let(:itt_year) { AcademicYear.new(2021) }
-
- it { is_expected.to be_empty }
- end
- end
-
- context "2023 claim year" do
- let(:claim_year) { AcademicYear.new(2023) }
-
- context "2018 ITT year" do
- let(:itt_year) { AcademicYear.new(2018) }
-
- it { is_expected.to contain_exactly(:mathematics) }
- end
-
- context "2019 ITT year" do
- let(:itt_year) { AcademicYear.new(2019) }
-
- it { is_expected.to be_empty }
- end
-
- context "2020 ITT year" do
- let(:itt_year) { AcademicYear.new(2020) }
-
- it { is_expected.to contain_exactly(:chemistry, :foreign_languages, :mathematics, :physics) }
- end
-
- context "2021 ITT year" do
- let(:itt_year) { AcademicYear.new(2021) }
-
- it { is_expected.to be_empty }
- end
-
- context "2022 ITT year" do
- let(:itt_year) { AcademicYear.new(2022) }
-
- it { is_expected.to be_empty }
- end
- end
-
- context "2024 claim year" do
- let(:claim_year) { AcademicYear.new(2024) }
-
- context "2019 ITT year" do
- let(:itt_year) { AcademicYear.new(2019) }
-
- it { is_expected.to contain_exactly(:mathematics) }
- end
-
- context "2020 ITT year" do
- let(:itt_year) { AcademicYear.new(2020) }
-
- it { is_expected.to contain_exactly(:chemistry, :foreign_languages, :mathematics, :physics) }
- end
-
- context "2021 ITT year" do
- let(:itt_year) { AcademicYear.new(2021) }
-
- it { is_expected.to be_empty }
- end
-
- context "2022 ITT year" do
- let(:itt_year) { AcademicYear.new(2022) }
-
- it { is_expected.to be_empty }
- end
-
- context "2023 ITT year" do
- let(:itt_year) { AcademicYear.new(2023) }
-
- it { is_expected.to be_empty }
- end
- end
- end
-
- context "LUP" do
- let(:policy) { Policies::LevellingUpPremiumPayments }
- let(:the_constant_lup_subjects) { [:chemistry, :computing, :mathematics, :physics] }
-
- context "claim year before 2022" do
- let(:claim_year) { AcademicYear.new(2021) }
- let(:itt_year) { AcademicYear.new(2017) }
-
- it { is_expected.to be_empty }
- end
-
- context "2022 claim year" do
- let(:claim_year) { AcademicYear.new(2022) }
-
- context "2017 itt year" do
- let(:itt_year) { AcademicYear.new(2017) }
-
- it { is_expected.to contain_exactly(*the_constant_lup_subjects) }
- end
-
- context "2018 itt year" do
- let(:itt_year) { AcademicYear.new(2018) }
-
- it { is_expected.to contain_exactly(*the_constant_lup_subjects) }
- end
-
- context "2019 itt year" do
- let(:itt_year) { AcademicYear.new(2019) }
-
- it { is_expected.to contain_exactly(*the_constant_lup_subjects) }
- end
-
- context "2020 itt year" do
- let(:itt_year) { AcademicYear.new(2020) }
-
- it { is_expected.to contain_exactly(*the_constant_lup_subjects) }
- end
-
- context "2021 itt year" do
- let(:itt_year) { AcademicYear.new(2021) }
-
- it { is_expected.to contain_exactly(*the_constant_lup_subjects) }
- end
- end
-
- context "2023 claim year" do
- let(:claim_year) { AcademicYear.new(2023) }
-
- context "2018 itt year" do
- let(:itt_year) { AcademicYear.new(2018) }
-
- it { is_expected.to contain_exactly(*the_constant_lup_subjects) }
- end
-
- context "2019 itt year" do
- let(:itt_year) { AcademicYear.new(2019) }
-
- it { is_expected.to contain_exactly(*the_constant_lup_subjects) }
- end
-
- context "2020 itt year" do
- let(:itt_year) { AcademicYear.new(2020) }
-
- it { is_expected.to contain_exactly(*the_constant_lup_subjects) }
- end
-
- context "2021 itt year" do
- let(:itt_year) { AcademicYear.new(2021) }
-
- it { is_expected.to contain_exactly(*the_constant_lup_subjects) }
- end
-
- context "2022 itt year" do
- let(:itt_year) { AcademicYear.new(2022) }
-
- it { is_expected.to contain_exactly(*the_constant_lup_subjects) }
- end
- end
-
- context "2024 claim year" do
- let(:claim_year) { AcademicYear.new(2024) }
-
- context "2019 itt year" do
- let(:itt_year) { AcademicYear.new(2019) }
-
- it { is_expected.to contain_exactly(*the_constant_lup_subjects) }
- end
-
- context "2020 itt year" do
- let(:itt_year) { AcademicYear.new(2020) }
-
- it { is_expected.to contain_exactly(*the_constant_lup_subjects) }
- end
-
- context "2021 itt year" do
- let(:itt_year) { AcademicYear.new(2021) }
-
- it { is_expected.to contain_exactly(*the_constant_lup_subjects) }
- end
-
- context "2022 itt year" do
- let(:itt_year) { AcademicYear.new(2022) }
-
- it { is_expected.to contain_exactly(*the_constant_lup_subjects) }
- end
-
- context "2023 itt year" do
- let(:itt_year) { AcademicYear.new(2023) }
-
- it { is_expected.to contain_exactly(*the_constant_lup_subjects) }
- end
- end
- end
-
- context "unsupported policy" do
- let(:policy) { Policies::StudentLoans }
-
- context "2022 claim year" do
- let(:claim_year) { AcademicYear.new(2022) }
-
- context "2017 ITT year" do
- let(:itt_year) { AcademicYear.new(2017) }
-
- specify { expect { described_class.new(claim_year: claim_year, itt_year: itt_year).current_subject_symbols(policy) }.to raise_error("Unsupported policy: StudentLoans") }
- end
- end
- end
- end
-
- describe "#future_subject_symbols" do
- subject { described_class.new(claim_year: claim_year, itt_year: itt_year).future_subject_symbols(policy) }
-
- context "ECP" do
- let(:policy) { Policies::EarlyCareerPayments }
-
- context "2022 claim year" do
- let(:claim_year) { AcademicYear.new(2022) }
-
- context "None of the above ITT year" do
- let(:itt_year) { AcademicYear.new }
-
- it { is_expected.to be_empty }
- end
-
- context "2017 ITT year" do
- let(:itt_year) { AcademicYear.new(2017) }
-
- it { is_expected.to be_empty }
- end
-
- context "2018 ITT year" do
- let(:itt_year) { AcademicYear.new(2018) }
-
- it { is_expected.to contain_exactly(:mathematics) }
- end
-
- context "2019 ITT year" do
- let(:itt_year) { AcademicYear.new(2019) }
-
- it { is_expected.to contain_exactly(:mathematics) }
- end
-
- context "2020 ITT year" do
- let(:itt_year) { AcademicYear.new(2020) }
-
- it { is_expected.to contain_exactly(:chemistry, :foreign_languages, :mathematics, :physics) }
- end
- end
-
- context "2023 claim year" do
- let(:claim_year) { AcademicYear.new(2023) }
-
- context "2018 ITT year" do
- let(:itt_year) { AcademicYear.new(2018) }
-
- it { is_expected.to be_empty }
- end
-
- context "2019 ITT year" do
- let(:itt_year) { AcademicYear.new(2019) }
-
- it { is_expected.to contain_exactly(:mathematics) }
- end
-
- context "2020 ITT year" do
- let(:itt_year) { AcademicYear.new(2020) }
-
- it { is_expected.to contain_exactly(:chemistry, :foreign_languages, :mathematics, :physics) }
- end
-
- context "2021 ITT year" do
- let(:itt_year) { AcademicYear.new(2021) }
-
- it { is_expected.to be_empty }
- end
-
- context "2022 ITT year" do
- let(:itt_year) { AcademicYear.new(2022) }
-
- it { is_expected.to be_empty }
- end
- end
-
- context "2024 claim year" do
- let(:claim_year) { AcademicYear.new(2024) }
-
- context "2019 ITT year" do
- let(:itt_year) { AcademicYear.new(2019) }
-
- it { is_expected.to be_empty }
- end
-
- context "2020 ITT year" do
- let(:itt_year) { AcademicYear.new(2020) }
-
- it { is_expected.to be_empty }
- end
-
- context "2021 ITT year" do
- let(:itt_year) { AcademicYear.new(2021) }
-
- it { is_expected.to be_empty }
- end
-
- context "2022 ITT year" do
- let(:itt_year) { AcademicYear.new(2022) }
-
- it { is_expected.to be_empty }
- end
-
- context "2023 ITT year" do
- let(:itt_year) { AcademicYear.new(2023) }
-
- it { is_expected.to be_empty }
- end
- end
- end
-
- context "LUP" do
- let(:policy) { Policies::LevellingUpPremiumPayments }
- let(:the_constant_lup_subjects) { [:chemistry, :computing, :mathematics, :physics] }
-
- context "2022 claim year" do
- let(:claim_year) { AcademicYear.new(2022) }
-
- context "2017 ITT year" do
- let(:itt_year) { AcademicYear.new(2017) }
-
- it { is_expected.to be_empty }
- end
-
- context "2018 ITT year" do
- let(:itt_year) { AcademicYear.new(2018) }
-
- it { is_expected.to contain_exactly(*the_constant_lup_subjects) }
- end
-
- context "2019 ITT year" do
- let(:itt_year) { AcademicYear.new(2019) }
-
- it { is_expected.to contain_exactly(*the_constant_lup_subjects) }
- end
-
- context "2020 ITT year" do
- let(:itt_year) { AcademicYear.new(2020) }
-
- it { is_expected.to contain_exactly(*the_constant_lup_subjects) }
- end
-
- context "2021 ITT year" do
- let(:itt_year) { AcademicYear.new(2021) }
-
- it { is_expected.to contain_exactly(*the_constant_lup_subjects) }
- end
- end
-
- context "2023 claim year" do
- let(:claim_year) { AcademicYear.new(2023) }
-
- context "2018 ITT year" do
- let(:itt_year) { AcademicYear.new(2018) }
-
- it { is_expected.to be_empty }
- end
-
- context "2019 ITT year" do
- let(:itt_year) { AcademicYear.new(2019) }
-
- it { is_expected.to contain_exactly(*the_constant_lup_subjects) }
- end
-
- context "2020 ITT year" do
- let(:itt_year) { AcademicYear.new(2020) }
-
- it { is_expected.to contain_exactly(*the_constant_lup_subjects) }
- end
-
- context "2021 ITT year" do
- let(:itt_year) { AcademicYear.new(2021) }
-
- it { is_expected.to contain_exactly(*the_constant_lup_subjects) }
- end
-
- context "2022 ITT year" do
- let(:itt_year) { AcademicYear.new(2022) }
-
- it { is_expected.to contain_exactly(*the_constant_lup_subjects) }
- end
- end
-
- context "2024 claim year" do
- let(:claim_year) { AcademicYear.new(2024) }
-
- context "2019 ITT year" do
- let(:itt_year) { AcademicYear.new(2019) }
-
- it { is_expected.to be_empty }
- end
-
- context "2020 ITT year" do
- let(:itt_year) { AcademicYear.new(2020) }
-
- it { is_expected.to be_empty }
- end
-
- context "2021 ITT year" do
- let(:itt_year) { AcademicYear.new(2021) }
-
- it { is_expected.to be_empty }
- end
-
- context "2022 ITT year" do
- let(:itt_year) { AcademicYear.new(2022) }
-
- it { is_expected.to be_empty }
- end
- end
- end
-
- context "unsupported policy" do
- let(:policy) { Policies::StudentLoans }
-
- context "2022 claim year" do
- let(:claim_year) { AcademicYear.new(2022) }
-
- context "2017 ITT year" do
- let(:itt_year) { AcademicYear.new(2017) }
-
- specify { expect { described_class.new(claim_year: claim_year, itt_year: itt_year).future_subject_symbols(policy) }.to raise_error("Unsupported policy: StudentLoans") }
- end
- end
- end
- end
-
- describe "#current_and_future_subject_symbols" do
- subject { described_class.new(claim_year: claim_year, itt_year: itt_year).current_and_future_subject_symbols(policy) }
-
- context "ECP" do
- let(:policy) { Policies::EarlyCareerPayments }
-
- context "2022 claim year" do
- let(:claim_year) { AcademicYear.new(2022) }
-
- context "None of the above ITT year" do
- let(:itt_year) { AcademicYear.new }
-
- it { is_expected.to be_empty }
- end
-
- context "2017 ITT year" do
- let(:itt_year) { AcademicYear.new(2017) }
-
- it { is_expected.to be_empty }
- end
-
- context "2018 ITT year" do
- let(:itt_year) { AcademicYear.new(2018) }
-
- it { is_expected.to contain_exactly(:mathematics) }
- end
-
- context "2019 ITT year" do
- let(:itt_year) { AcademicYear.new(2019) }
-
- it { is_expected.to contain_exactly(:mathematics) }
- end
-
- context "2020 ITT year" do
- let(:itt_year) { AcademicYear.new(2020) }
-
- it { is_expected.to contain_exactly(:chemistry, :foreign_languages, :mathematics, :physics) }
- end
- end
-
- context "2023 claim year" do
- let(:claim_year) { AcademicYear.new(2023) }
-
- context "2018 ITT year" do
- let(:itt_year) { AcademicYear.new(2018) }
-
- it { is_expected.to contain_exactly(:mathematics) }
- end
-
- context "2019 ITT year" do
- let(:itt_year) { AcademicYear.new(2019) }
-
- it { is_expected.to contain_exactly(:mathematics) }
- end
-
- context "2020 ITT year" do
- let(:itt_year) { AcademicYear.new(2020) }
-
- it { is_expected.to contain_exactly(:chemistry, :foreign_languages, :mathematics, :physics) }
- end
-
- context "2021 ITT year" do
- let(:itt_year) { AcademicYear.new(2021) }
-
- it { is_expected.to be_empty }
- end
-
- context "2022 ITT year" do
- let(:itt_year) { AcademicYear.new(2022) }
-
- it { is_expected.to be_empty }
- end
- end
-
- context "2024 claim year" do
- let(:claim_year) { AcademicYear.new(2024) }
-
- context "2019 ITT year" do
- let(:itt_year) { AcademicYear.new(2019) }
-
- it { is_expected.to contain_exactly(:mathematics) }
- end
-
- context "2020 ITT year" do
- let(:itt_year) { AcademicYear.new(2020) }
-
- it { is_expected.to contain_exactly(:chemistry, :foreign_languages, :mathematics, :physics) }
- end
-
- context "2021 ITT year" do
- let(:itt_year) { AcademicYear.new(2021) }
-
- it { is_expected.to be_empty }
- end
-
- context "2022 ITT year" do
- let(:itt_year) { AcademicYear.new(2022) }
-
- it { is_expected.to be_empty }
- end
-
- context "2023 ITT year" do
- let(:itt_year) { AcademicYear.new(2023) }
-
- it { is_expected.to be_empty }
- end
- end
- end
-
- context "LUP" do
- let(:policy) { Policies::LevellingUpPremiumPayments }
- let(:the_constant_lup_subjects) { [:chemistry, :computing, :mathematics, :physics] }
-
- context "2022 claim year" do
- let(:claim_year) { AcademicYear.new(2022) }
-
- context "2017 ITT year" do
- let(:itt_year) { AcademicYear.new(2017) }
-
- it { is_expected.to contain_exactly(:chemistry, :computing, :mathematics, :physics) }
- end
-
- context "2018 ITT year" do
- let(:itt_year) { AcademicYear.new(2018) }
-
- it { is_expected.to contain_exactly(*the_constant_lup_subjects) }
- end
-
- context "2019 ITT year" do
- let(:itt_year) { AcademicYear.new(2019) }
-
- it { is_expected.to contain_exactly(*the_constant_lup_subjects) }
- end
-
- context "2020 ITT year" do
- let(:itt_year) { AcademicYear.new(2020) }
-
- it { is_expected.to contain_exactly(*the_constant_lup_subjects) }
- end
-
- context "2021 ITT year" do
- let(:itt_year) { AcademicYear.new(2021) }
-
- it { is_expected.to contain_exactly(*the_constant_lup_subjects) }
- end
- end
-
- context "2023 claim year" do
- let(:claim_year) { AcademicYear.new(2023) }
-
- context "2018 ITT year" do
- let(:itt_year) { AcademicYear.new(2018) }
-
- it { is_expected.to contain_exactly(:chemistry, :computing, :mathematics, :physics) }
- end
-
- context "2019 ITT year" do
- let(:itt_year) { AcademicYear.new(2019) }
-
- it { is_expected.to contain_exactly(*the_constant_lup_subjects) }
- end
-
- context "2020 ITT year" do
- let(:itt_year) { AcademicYear.new(2020) }
-
- it { is_expected.to contain_exactly(*the_constant_lup_subjects) }
- end
-
- context "2021 ITT year" do
- let(:itt_year) { AcademicYear.new(2021) }
-
- it { is_expected.to contain_exactly(*the_constant_lup_subjects) }
- end
-
- context "2022 ITT year" do
- let(:itt_year) { AcademicYear.new(2022) }
-
- it { is_expected.to contain_exactly(*the_constant_lup_subjects) }
- end
- end
-
- context "2024 claim year" do
- let(:claim_year) { AcademicYear.new(2024) }
-
- context "2019 ITT year" do
- let(:itt_year) { AcademicYear.new(2019) }
-
- it { is_expected.to contain_exactly(:chemistry, :computing, :mathematics, :physics) }
- end
-
- context "2020 ITT year" do
- let(:itt_year) { AcademicYear.new(2020) }
-
- it { is_expected.to contain_exactly(:chemistry, :computing, :mathematics, :physics) }
- end
-
- context "2021 ITT year" do
- let(:itt_year) { AcademicYear.new(2021) }
-
- it { is_expected.to contain_exactly(:chemistry, :computing, :mathematics, :physics) }
- end
-
- context "2022 ITT year" do
- let(:itt_year) { AcademicYear.new(2022) }
-
- it { is_expected.to contain_exactly(:chemistry, :computing, :mathematics, :physics) }
- end
- end
- end
-
- context "unsupported policy" do
- let(:policy) { Policies::StudentLoans }
-
- context "2022 claim year" do
- let(:claim_year) { AcademicYear.new(2022) }
-
- context "2017 ITT year" do
- let(:itt_year) { AcademicYear.new(2017) }
-
- specify { expect { described_class.new(claim_year: claim_year, itt_year: itt_year).future_subject_symbols(policy) }.to raise_error("Unsupported policy: StudentLoans") }
- end
- end
- end
- end
-
- describe "#selectable_subject_symbols" do
- subject do
- described_class.new(
- claim_year: claim_year, itt_year: itt_year
- ).selectable_subject_symbols(journey_session.answers)
- end
-
- context "when academic year is 2022" do
- before { create(:journey_configuration, :additional_payments, current_academic_year: AcademicYear.new(2022)) }
-
- context "2022 claim year" do
- let(:claim_year) { AcademicYear.new(2022) }
-
- context "None of the above ITT year" do
- let(:itt_year) { AcademicYear.new }
-
- let(:journey_session) do
- create(:additional_payments_session)
- end
-
- it { is_expected.to be_empty }
- end
-
- context "2017 ITT year" do
- let(:itt_year) { AcademicYear.new(2017) }
-
- context "ineligible LUP" do
- let(:journey_session) do
- create(
- :additional_payments_session,
- answers: attributes_for(
- :additional_payments_answers,
- :ecp_eligible,
- itt_academic_year: itt_year
- )
- )
- end
-
- it { is_expected.to be_empty }
- end
-
- context "eligible LUP" do
- let(:journey_session) do
- create(
- :additional_payments_session,
- answers: attributes_for(
- :additional_payments_answers,
- :ecp_and_lup_eligible,
- itt_academic_year: itt_year
- )
- )
- end
-
- it { is_expected.to contain_exactly(:chemistry, :computing, :mathematics, :physics) }
- end
- end
-
- context "2018 ITT year" do
- let(:itt_year) { AcademicYear.new(2018) }
-
- context "ineligible LUP" do
- let(:journey_session) do
- create(
- :additional_payments_session,
- answers: attributes_for(
- :additional_payments_answers,
- :ecp_eligible,
- itt_academic_year: itt_year
- )
- )
- end
-
- it { is_expected.to contain_exactly(:mathematics) }
- end
-
- context "eligible LUP" do
- let(:journey_session) do
- create(
- :additional_payments_session,
- answers: attributes_for(
- :additional_payments_answers,
- :ecp_and_lup_eligible,
- itt_academic_year: itt_year
- )
- )
- end
-
- it { is_expected.to contain_exactly(:chemistry, :computing, :mathematics, :physics) }
- end
- end
-
- context "2019 ITT year" do
- let(:itt_year) { AcademicYear.new(2019) }
-
- context "ineligible LUP" do
- let(:journey_session) do
- create(
- :additional_payments_session,
- answers: attributes_for(
- :additional_payments_answers,
- :ecp_eligible,
- itt_academic_year: itt_year
- )
- )
- end
-
- it { is_expected.to contain_exactly(:mathematics) }
- end
-
- context "eligible LUP" do
- let(:journey_session) do
- create(
- :additional_payments_session,
- answers: attributes_for(
- :additional_payments_answers,
- :ecp_and_lup_eligible,
- itt_academic_year: itt_year
- )
- )
- end
-
- it { is_expected.to contain_exactly(:chemistry, :computing, :mathematics, :physics) }
- end
- end
-
- context "2020 ITT year" do
- let(:itt_year) { AcademicYear.new(2020) }
-
- context "ineligible LUP" do
- let(:journey_session) do
- create(
- :additional_payments_session,
- answers: attributes_for(
- :additional_payments_answers,
- :ecp_eligible,
- itt_academic_year: itt_year
- )
- )
- end
-
- it { is_expected.to contain_exactly(:chemistry, :foreign_languages, :mathematics, :physics) }
- end
-
- context "eligible LUP" do
- let(:journey_session) do
- create(
- :additional_payments_session,
- answers: attributes_for(
- :additional_payments_answers,
- :ecp_and_lup_eligible,
- itt_academic_year: itt_year
- )
- )
- end
-
- it { is_expected.to contain_exactly(:chemistry, :computing, :foreign_languages, :mathematics, :physics) }
- end
- end
-
- context "2021 ITT year" do
- let(:itt_year) { AcademicYear.new(2021) }
-
- context "ineligible LUP" do
- let(:journey_session) do
- create(
- :additional_payments_session,
- answers: attributes_for(
- :additional_payments_answers,
- :ecp_eligible,
- itt_academic_year: itt_year
- )
- )
- end
-
- it { is_expected.to be_empty }
- end
-
- context "eligible LUP" do
- let(:journey_session) do
- create(
- :additional_payments_session,
- answers: attributes_for(
- :additional_payments_answers,
- :ecp_and_lup_eligible,
- itt_academic_year: itt_year
- )
- )
- end
-
- it { is_expected.to contain_exactly(:chemistry, :computing, :mathematics, :physics) }
- end
- end
- end
- end
- end
-
- describe ".first_eligible_itt_year_for_subject" do
- subject { described_class.first_eligible_itt_year_for_subject(policy: policy, claim_year: claim_year, subject_symbol: subject_symbol) }
-
- context "string instead of symbol" do
- specify { expect { described_class.first_eligible_itt_year_for_subject(policy: Policies::EarlyCareerPayments, claim_year: AcademicYear.new(2022), subject_symbol: "mathematics") }.to raise_error "[mathematics] is not a symbol" }
- end
-
- context "ECP" do
- let(:policy) { Policies::EarlyCareerPayments }
-
- context "2022 claim year" do
- let(:claim_year) { AcademicYear.new(2022) }
-
- context "mathematics" do
- let(:subject_symbol) { :mathematics }
-
- it { is_expected.to eq(AcademicYear.new(2019)) }
- end
-
- context "physics" do
- let(:subject_symbol) { :physics }
-
- it { is_expected.to eq(AcademicYear.new(2020)) }
- end
-
- context "chemistry" do
- let(:subject_symbol) { :chemistry }
-
- it { is_expected.to eq(AcademicYear.new(2020)) }
- end
-
- context "computing" do
- let(:subject_symbol) { :computing }
-
- it { is_expected.to be_nil }
- end
-
- context "languages" do
- let(:subject_symbol) { :foreign_languages }
-
- it { is_expected.to eq(AcademicYear.new(2020)) }
- end
- end
-
- context "2023 claim year" do
- let(:claim_year) { AcademicYear.new(2023) }
-
- context "mathematics" do
- let(:subject_symbol) { :mathematics }
-
- it { is_expected.to eq(AcademicYear.new(2018)) }
- end
-
- context "physics" do
- let(:subject_symbol) { :physics }
-
- it { is_expected.to eq(AcademicYear.new(2020)) }
- end
-
- context "chemistry" do
- let(:subject_symbol) { :chemistry }
-
- it { is_expected.to eq(AcademicYear.new(2020)) }
- end
-
- context "computing" do
- let(:subject_symbol) { :computing }
-
- it { is_expected.to be_nil }
- end
-
- context "languages" do
- let(:subject_symbol) { :foreign_languages }
-
- it { is_expected.to eq(AcademicYear.new(2020)) }
- end
- end
-
- context "2024 claim year" do
- let(:claim_year) { AcademicYear.new(2024) }
-
- context "mathematics" do
- let(:subject_symbol) { :mathematics }
-
- it { is_expected.to eq(AcademicYear.new(2019)) }
- end
-
- context "physics" do
- let(:subject_symbol) { :physics }
-
- it { is_expected.to eq(AcademicYear.new(2020)) }
- end
-
- context "chemistry" do
- let(:subject_symbol) { :chemistry }
-
- it { is_expected.to eq(AcademicYear.new(2020)) }
- end
-
- context "computing" do
- let(:subject_symbol) { :computing }
-
- it { is_expected.to be_nil }
- end
-
- context "languages" do
- let(:subject_symbol) { :foreign_languages }
-
- it { is_expected.to eq(AcademicYear.new(2020)) }
- end
- end
- end
-
- context "LUP" do
- let(:policy) { Policies::LevellingUpPremiumPayments }
-
- context "2022 claim year" do
- let(:claim_year) { AcademicYear.new(2022) }
-
- context "mathematics" do
- let(:subject_symbol) { :mathematics }
-
- it { is_expected.to eq(AcademicYear.new(2017)) }
- end
-
- context "physics" do
- let(:subject_symbol) { :physics }
-
- it { is_expected.to eq(AcademicYear.new(2017)) }
- end
-
- context "chemistry" do
- let(:subject_symbol) { :chemistry }
-
- it { is_expected.to eq(AcademicYear.new(2017)) }
- end
-
- context "languages" do
- let(:subject_symbol) { :foreign_languages }
-
- it { is_expected.to be_nil }
- end
- end
-
- context "2023 claim year" do
- let(:claim_year) { AcademicYear.new(2023) }
-
- context "mathematics" do
- let(:subject_symbol) { :mathematics }
-
- it { is_expected.to eq(AcademicYear.new(2018)) }
- end
-
- context "physics" do
- let(:subject_symbol) { :physics }
-
- it { is_expected.to eq(AcademicYear.new(2018)) }
- end
-
- context "chemistry" do
- let(:subject_symbol) { :chemistry }
-
- it { is_expected.to eq(AcademicYear.new(2018)) }
- end
-
- context "languages" do
- let(:subject_symbol) { :foreign_languages }
-
- it { is_expected.to be_nil }
- end
- end
-
- context "2024 claim year" do
- let(:claim_year) { AcademicYear.new(2024) }
-
- context "mathematics" do
- let(:subject_symbol) { :mathematics }
-
- it { is_expected.to eq(AcademicYear.new(2019)) }
- end
-
- context "physics" do
- let(:subject_symbol) { :physics }
-
- it { is_expected.to eq(AcademicYear.new(2019)) }
- end
-
- context "chemistry" do
- let(:subject_symbol) { :chemistry }
-
- it { is_expected.to eq(AcademicYear.new(2019)) }
- end
-
- context "languages" do
- let(:subject_symbol) { :foreign_languages }
-
- it { is_expected.to be_nil }
- end
- end
- end
- end
-
- describe ".fixed_lup_subject_symbols" do
- specify { expect(described_class.fixed_lup_subject_symbols).to contain_exactly(:chemistry, :computing, :mathematics, :physics) }
- end
-end
diff --git a/spec/models/early_career_payments_spec.rb b/spec/models/early_career_payments_spec.rb
index 40f6498a9a..180a47247a 100644
--- a/spec/models/early_career_payments_spec.rb
+++ b/spec/models/early_career_payments_spec.rb
@@ -31,4 +31,135 @@
subject(:payroll_file_name) { described_class.payroll_file_name }
it { is_expected.to eq("EarlyCareerPayments") }
end
+
+ describe ".current_and_future_subject_symbols" do
+ subject(:current_and_future_subject_symbols) do
+ described_class.current_and_future_subject_symbols(
+ claim_year: claim_year,
+ itt_year: itt_year
+ )
+ end
+
+ context "2022 claim year" do
+ let(:claim_year) { AcademicYear.new(2022) }
+
+ context "None of the above ITT year" do
+ let(:itt_year) { AcademicYear.new }
+
+ it { is_expected.to be_empty }
+ end
+
+ context "2017 ITT year" do
+ let(:itt_year) { AcademicYear.new(2017) }
+
+ it { is_expected.to be_empty }
+ end
+
+ context "2018 ITT year" do
+ let(:itt_year) { AcademicYear.new(2018) }
+
+ it { is_expected.to contain_exactly(:mathematics) }
+ end
+
+ context "2019 ITT year" do
+ let(:itt_year) { AcademicYear.new(2019) }
+
+ it { is_expected.to contain_exactly(:mathematics) }
+ end
+
+ context "2020 ITT year" do
+ let(:itt_year) { AcademicYear.new(2020) }
+
+ it { is_expected.to contain_exactly(:chemistry, :foreign_languages, :mathematics, :physics) }
+ end
+ end
+
+ context "2023 claim year" do
+ let(:claim_year) { AcademicYear.new(2023) }
+
+ context "2018 ITT year" do
+ let(:itt_year) { AcademicYear.new(2018) }
+
+ it { is_expected.to contain_exactly(:mathematics) }
+ end
+
+ context "2019 ITT year" do
+ let(:itt_year) { AcademicYear.new(2019) }
+
+ it { is_expected.to contain_exactly(:mathematics) }
+ end
+
+ context "2020 ITT year" do
+ let(:itt_year) { AcademicYear.new(2020) }
+
+ it { is_expected.to contain_exactly(:chemistry, :foreign_languages, :mathematics, :physics) }
+ end
+
+ context "2021 ITT year" do
+ let(:itt_year) { AcademicYear.new(2021) }
+
+ it { is_expected.to be_empty }
+ end
+
+ context "2022 ITT year" do
+ let(:itt_year) { AcademicYear.new(2022) }
+
+ it { is_expected.to be_empty }
+ end
+ end
+
+ context "2024 claim year" do
+ let(:claim_year) { AcademicYear.new(2024) }
+
+ context "2019 ITT year" do
+ let(:itt_year) { AcademicYear.new(2019) }
+
+ it { is_expected.to contain_exactly(:mathematics) }
+ end
+
+ context "2020 ITT year" do
+ let(:itt_year) { AcademicYear.new(2020) }
+
+ it { is_expected.to contain_exactly(:chemistry, :foreign_languages, :mathematics, :physics) }
+ end
+
+ context "2021 ITT year" do
+ let(:itt_year) { AcademicYear.new(2021) }
+
+ it { is_expected.to be_empty }
+ end
+
+ context "2022 ITT year" do
+ let(:itt_year) { AcademicYear.new(2022) }
+
+ it { is_expected.to be_empty }
+ end
+
+ context "2023 ITT year" do
+ let(:itt_year) { AcademicYear.new(2023) }
+
+ it { is_expected.to be_empty }
+ end
+ end
+ end
+
+ describe ".selectable_itt_years_for_view" do
+ context "2022/2023 claim year" do
+ subject { described_class.selectable_itt_years_for_claim_year(AcademicYear.new(2022)) }
+
+ it { is_expected.to eq([AcademicYear.new(2017), AcademicYear.new(2018), AcademicYear.new(2019), AcademicYear.new(2020), AcademicYear.new(2021)]) }
+ end
+
+ context "2023/2024 claim year" do
+ subject { described_class.selectable_itt_years_for_claim_year(AcademicYear.new(2023)) }
+
+ it { is_expected.to eq([AcademicYear.new(2018), AcademicYear.new(2019), AcademicYear.new(2020), AcademicYear.new(2021), AcademicYear.new(2022)]) }
+ end
+
+ context "2024/2025 claim year" do
+ subject { described_class.selectable_itt_years_for_claim_year(AcademicYear.new(2024)) }
+
+ it { is_expected.to eq([AcademicYear.new(2019), AcademicYear.new(2020), AcademicYear.new(2021), AcademicYear.new(2022), AcademicYear.new(2023)]) }
+ end
+ end
end
diff --git a/spec/models/journeys/additional_payments_for_teaching_spec.rb b/spec/models/journeys/additional_payments_for_teaching_spec.rb
index f9be210508..3d111ccb4b 100644
--- a/spec/models/journeys/additional_payments_for_teaching_spec.rb
+++ b/spec/models/journeys/additional_payments_for_teaching_spec.rb
@@ -68,7 +68,7 @@
end
shared_examples "true for years" do |start_years_range, policy_year|
- JourneySubjectEligibilityChecker.selectable_itt_years_for_claim_year(policy_year).each do |itt_academic_year|
+ Journeys::AdditionalPaymentsForTeaching.selectable_itt_years_for_claim_year(policy_year).each do |itt_academic_year|
context "ITT year #{itt_academic_year}" do
let(:itt_academic_year) { itt_academic_year }
@@ -82,7 +82,7 @@
end
shared_examples "false for all years" do |policy_year|
- JourneySubjectEligibilityChecker.selectable_itt_years_for_claim_year(policy_year).each do |itt_academic_year|
+ Journeys::AdditionalPaymentsForTeaching.selectable_itt_years_for_claim_year(policy_year).each do |itt_academic_year|
context "ITT year #{itt_academic_year}" do
let(:itt_academic_year) { itt_academic_year }
@@ -128,4 +128,202 @@
end
end
end
+
+ describe ".selectable_subject_symbols" do
+ subject { described_class.selectable_subject_symbols(journey_session) }
+
+ context "when academic year is 2022" do
+ before { create(:journey_configuration, :additional_payments, current_academic_year: claim_year) }
+
+ context "2022 claim year" do
+ let(:claim_year) { AcademicYear.new(2022) }
+
+ context "None of the above ITT year" do
+ let(:itt_year) { AcademicYear.new }
+
+ let(:journey_session) do
+ create(
+ :additional_payments_session,
+ answers: attributes_for(
+ :additional_payments_answers,
+ itt_academic_year: itt_year
+ )
+ )
+ end
+
+ it { is_expected.to be_empty }
+ end
+
+ context "2017 ITT year" do
+ let(:itt_year) { AcademicYear.new(2017) }
+
+ context "ineligible LUP" do
+ let(:journey_session) do
+ create(
+ :additional_payments_session,
+ answers: attributes_for(
+ :additional_payments_answers,
+ :ecp_eligible,
+ itt_academic_year: itt_year
+ )
+ )
+ end
+
+ it { is_expected.to be_empty }
+ end
+
+ context "eligible LUP" do
+ let(:journey_session) do
+ create(
+ :additional_payments_session,
+ answers: attributes_for(
+ :additional_payments_answers,
+ :ecp_and_lup_eligible,
+ itt_academic_year: itt_year
+ )
+ )
+ end
+
+ it { is_expected.to contain_exactly(:chemistry, :computing, :mathematics, :physics) }
+ end
+ end
+
+ context "2018 ITT year" do
+ let(:itt_year) { AcademicYear.new(2018) }
+
+ context "ineligible LUP" do
+ let(:journey_session) do
+ create(
+ :additional_payments_session,
+ answers: attributes_for(
+ :additional_payments_answers,
+ :ecp_eligible,
+ itt_academic_year: itt_year
+ )
+ )
+ end
+
+ it { is_expected.to contain_exactly(:mathematics) }
+ end
+
+ context "eligible LUP" do
+ let(:journey_session) do
+ create(
+ :additional_payments_session,
+ answers: attributes_for(
+ :additional_payments_answers,
+ :ecp_and_lup_eligible,
+ itt_academic_year: itt_year
+ )
+ )
+ end
+
+ it { is_expected.to contain_exactly(:chemistry, :computing, :mathematics, :physics) }
+ end
+ end
+
+ context "2019 ITT year" do
+ let(:itt_year) { AcademicYear.new(2019) }
+
+ context "ineligible LUP" do
+ let(:journey_session) do
+ create(
+ :additional_payments_session,
+ answers: attributes_for(
+ :additional_payments_answers,
+ :ecp_eligible,
+ itt_academic_year: itt_year
+ )
+ )
+ end
+
+ it { is_expected.to contain_exactly(:mathematics) }
+ end
+
+ context "eligible LUP" do
+ let(:journey_session) do
+ create(
+ :additional_payments_session,
+ answers: attributes_for(
+ :additional_payments_answers,
+ :ecp_and_lup_eligible,
+ itt_academic_year: itt_year
+ )
+ )
+ end
+
+ it { is_expected.to contain_exactly(:chemistry, :computing, :mathematics, :physics) }
+ end
+ end
+
+ context "2020 ITT year" do
+ let(:itt_year) { AcademicYear.new(2020) }
+
+ context "ineligible LUP" do
+ let(:journey_session) do
+ create(
+ :additional_payments_session,
+ answers: attributes_for(
+ :additional_payments_answers,
+ :ecp_eligible,
+ itt_academic_year: itt_year
+ )
+ )
+ end
+
+ it { is_expected.to contain_exactly(:chemistry, :foreign_languages, :mathematics, :physics) }
+ end
+
+ context "eligible LUP" do
+ let(:journey_session) do
+ create(
+ :additional_payments_session,
+ answers: attributes_for(
+ :additional_payments_answers,
+ :ecp_and_lup_eligible,
+ itt_academic_year: itt_year
+ )
+ )
+ end
+
+ it { is_expected.to contain_exactly(:chemistry, :computing, :foreign_languages, :mathematics, :physics) }
+ end
+ end
+
+ context "2021 ITT year" do
+ let(:itt_year) { AcademicYear.new(2021) }
+
+ context "ineligible LUP" do
+ let(:journey_session) do
+ create(
+ :additional_payments_session,
+ answers: attributes_for(
+ :additional_payments_answers,
+ :ecp_eligible,
+ itt_academic_year: itt_year
+ )
+ )
+ end
+
+ it { is_expected.to be_empty }
+ end
+
+ context "eligible LUP" do
+ let(:journey_session) do
+ create(
+ :additional_payments_session,
+ answers: attributes_for(
+ :additional_payments_answers,
+ :ecp_and_lup_eligible,
+ itt_academic_year: itt_year
+ )
+ )
+ end
+
+ it { is_expected.to contain_exactly(:chemistry, :computing, :mathematics, :physics) }
+ end
+ end
+ end
+ end
+ end
end
diff --git a/spec/models/levelling_up_premium_payments_spec.rb b/spec/models/levelling_up_premium_payments_spec.rb
index 702123cab7..46dfc3e105 100644
--- a/spec/models/levelling_up_premium_payments_spec.rb
+++ b/spec/models/levelling_up_premium_payments_spec.rb
@@ -29,4 +29,133 @@
subject(:payroll_file_name) { described_class.payroll_file_name }
it { is_expected.to eq("SchoolsLUP") }
end
+
+ describe ".current_and_future_subject_symbols" do
+ subject(:current_and_future_subject_symbols) do
+ described_class.current_and_future_subject_symbols(
+ claim_year: claim_year,
+ itt_year: itt_year
+ )
+ end
+
+ let(:the_constant_lup_subjects) do
+ [:chemistry, :computing, :mathematics, :physics]
+ end
+
+ context "2022 claim year" do
+ let(:claim_year) { AcademicYear.new(2022) }
+
+ context "2017 ITT year" do
+ let(:itt_year) { AcademicYear.new(2017) }
+
+ it { is_expected.to contain_exactly(:chemistry, :computing, :mathematics, :physics) }
+ end
+
+ context "2018 ITT year" do
+ let(:itt_year) { AcademicYear.new(2018) }
+
+ it { is_expected.to contain_exactly(*the_constant_lup_subjects) }
+ end
+
+ context "2019 ITT year" do
+ let(:itt_year) { AcademicYear.new(2019) }
+
+ it { is_expected.to contain_exactly(*the_constant_lup_subjects) }
+ end
+
+ context "2020 ITT year" do
+ let(:itt_year) { AcademicYear.new(2020) }
+
+ it { is_expected.to contain_exactly(*the_constant_lup_subjects) }
+ end
+
+ context "2021 ITT year" do
+ let(:itt_year) { AcademicYear.new(2021) }
+
+ it { is_expected.to contain_exactly(*the_constant_lup_subjects) }
+ end
+ end
+
+ context "2023 claim year" do
+ let(:claim_year) { AcademicYear.new(2023) }
+
+ context "2018 ITT year" do
+ let(:itt_year) { AcademicYear.new(2018) }
+
+ it { is_expected.to contain_exactly(:chemistry, :computing, :mathematics, :physics) }
+ end
+
+ context "2019 ITT year" do
+ let(:itt_year) { AcademicYear.new(2019) }
+
+ it { is_expected.to contain_exactly(*the_constant_lup_subjects) }
+ end
+
+ context "2020 ITT year" do
+ let(:itt_year) { AcademicYear.new(2020) }
+
+ it { is_expected.to contain_exactly(*the_constant_lup_subjects) }
+ end
+
+ context "2021 ITT year" do
+ let(:itt_year) { AcademicYear.new(2021) }
+
+ it { is_expected.to contain_exactly(*the_constant_lup_subjects) }
+ end
+
+ context "2022 ITT year" do
+ let(:itt_year) { AcademicYear.new(2022) }
+
+ it { is_expected.to contain_exactly(*the_constant_lup_subjects) }
+ end
+ end
+
+ context "2024 claim year" do
+ let(:claim_year) { AcademicYear.new(2024) }
+
+ context "2019 ITT year" do
+ let(:itt_year) { AcademicYear.new(2019) }
+
+ it { is_expected.to contain_exactly(:chemistry, :computing, :mathematics, :physics) }
+ end
+
+ context "2020 ITT year" do
+ let(:itt_year) { AcademicYear.new(2020) }
+
+ it { is_expected.to contain_exactly(:chemistry, :computing, :mathematics, :physics) }
+ end
+
+ context "2021 ITT year" do
+ let(:itt_year) { AcademicYear.new(2021) }
+
+ it { is_expected.to contain_exactly(:chemistry, :computing, :mathematics, :physics) }
+ end
+
+ context "2022 ITT year" do
+ let(:itt_year) { AcademicYear.new(2022) }
+
+ it { is_expected.to contain_exactly(:chemistry, :computing, :mathematics, :physics) }
+ end
+ end
+ end
+
+ describe ".selectable_itt_years_for_view" do
+ context "2022/2023 claim year" do
+ subject { described_class.selectable_itt_years_for_claim_year(AcademicYear.new(2022)) }
+
+ it { is_expected.to eq([AcademicYear.new(2017), AcademicYear.new(2018), AcademicYear.new(2019), AcademicYear.new(2020), AcademicYear.new(2021)]) }
+ end
+
+ context "2023/2024 claim year" do
+ subject { described_class.selectable_itt_years_for_claim_year(AcademicYear.new(2023)) }
+
+ it { is_expected.to eq([AcademicYear.new(2018), AcademicYear.new(2019), AcademicYear.new(2020), AcademicYear.new(2021), AcademicYear.new(2022)]) }
+ end
+
+ context "2024/2025 claim year" do
+ subject { described_class.selectable_itt_years_for_claim_year(AcademicYear.new(2024)) }
+
+ it { is_expected.to eq([AcademicYear.new(2019), AcademicYear.new(2020), AcademicYear.new(2021), AcademicYear.new(2022), AcademicYear.new(2023)]) }
+ end
+ end
end
diff --git a/spec/models/policies/early_career_payments/dqt_record_spec.rb b/spec/models/policies/early_career_payments/dqt_record_spec.rb
index 24ddbc1e97..c30fb04b2f 100644
--- a/spec/models/policies/early_career_payments/dqt_record_spec.rb
+++ b/spec/models/policies/early_career_payments/dqt_record_spec.rb
@@ -2176,8 +2176,10 @@
context "with a valid ITT year" do
before do
- allow(JourneySubjectEligibilityChecker).to receive(:new)
- .and_return(double(current_and_future_subject_symbols: eligible_subjects))
+ allow(Policies::EarlyCareerPayments).to(
+ receive(:current_and_future_subject_symbols)
+ .and_return(eligible_subjects)
+ )
end
let(:claim_academic_year) { AcademicYear.new(2023) }
@@ -2249,7 +2251,7 @@
let(:itt_subjects) { ["mathematics"] }
before do
- allow(JourneySubjectEligibilityChecker).to receive(:new)
+ allow(Policies::EarlyCareerPayments).to receive(:current_and_future_subject_symbols)
.and_raise(StandardError.new("ITT year"))
end
@@ -2261,8 +2263,9 @@
describe "#itt_academic_year_for_claim" do
before do
- allow(JourneySubjectEligibilityChecker).to receive(:new)
- .and_return(double(selectable_itt_years_for_claim_year: eligible_years))
+ allow(Policies::EarlyCareerPayments).to(
+ receive(:selectable_itt_years_for_claim_year).and_return(eligible_years)
+ )
end
let(:record) do
diff --git a/spec/models/policies/early_career_payments/eligibility_spec.rb b/spec/models/policies/early_career_payments/eligibility_spec.rb
index c4e7f008a3..4afb7a0527 100644
--- a/spec/models/policies/early_career_payments/eligibility_spec.rb
+++ b/spec/models/policies/early_career_payments/eligibility_spec.rb
@@ -3,6 +3,14 @@
require "rails_helper"
RSpec.describe Policies::EarlyCareerPayments::Eligibility, type: :model do
+ let(:academic_year) do
+ Policies::EarlyCareerPayments::Eligibility::ITT_ACADEMIC_YEARS.keys.first
+ end
+
+ before do
+ create(:journey_configuration, :additional_payments)
+ end
+
describe "#policy" do
let(:early_career_payments_eligibility) { build(:early_career_payments_eligibility) }
@@ -16,7 +24,7 @@
context "current_school not set and school_somewhere_else is not set return one is required error" do
it "returns an error" do
- eligibility = Policies::EarlyCareerPayments::Eligibility.new(current_school: nil, school_somewhere_else: nil)
+ eligibility = Policies::EarlyCareerPayments::Eligibility.new(current_school: nil, school_somewhere_else: nil, itt_academic_year: academic_year)
expect(eligibility).not_to be_valid(:"correct-school")
expect(eligibility.errors.messages[:current_school]).to eq(["Select the school you teach at or choose somewhere else"])
@@ -25,7 +33,7 @@
context "selects a school suggested from TPS" do
it "sets current_school and sets school_somewhere_else to false" do
- eligibility = Policies::EarlyCareerPayments::Eligibility.new(current_school: school, school_somewhere_else: false)
+ eligibility = Policies::EarlyCareerPayments::Eligibility.new(current_school: school, school_somewhere_else: false, itt_academic_year: academic_year)
expect(eligibility).to be_valid(:"correct-school")
end
@@ -33,14 +41,14 @@
context "selects somewhere else and not the suggested school" do
it "sets school_somewhere_else to true and current_school stays nil" do
- eligibility = Policies::EarlyCareerPayments::Eligibility.new(current_school: nil, school_somewhere_else: true)
+ eligibility = Policies::EarlyCareerPayments::Eligibility.new(current_school: nil, school_somewhere_else: true, itt_academic_year: academic_year)
expect(eligibility).to be_valid(:"correct-school")
end
# e.g. the teacher presses the backlink a school is already set
it "sets school_somewhere_else to true and current_school stays remains if already set" do
- eligibility = Policies::EarlyCareerPayments::Eligibility.new(current_school: school, school_somewhere_else: true)
+ eligibility = Policies::EarlyCareerPayments::Eligibility.new(current_school: school, school_somewhere_else: true, itt_academic_year: academic_year)
expect(eligibility).to be_valid(:"correct-school")
end
@@ -108,18 +116,18 @@
end
it "validates that award_amount is a positive number" do
- expect(Policies::EarlyCareerPayments::Eligibility.new(award_amount: -1_000)).not_to be_valid
- expect(Policies::EarlyCareerPayments::Eligibility.new(award_amount: 2_500)).to be_valid
+ expect(Policies::EarlyCareerPayments::Eligibility.new(award_amount: -1_000, itt_academic_year: academic_year)).not_to be_valid
+ expect(Policies::EarlyCareerPayments::Eligibility.new(award_amount: 2_500, itt_academic_year: academic_year)).to be_valid
end
it "validates that award_amount can be zero" do
- expect(Policies::EarlyCareerPayments::Eligibility.new(award_amount: 0)).to be_valid
+ expect(Policies::EarlyCareerPayments::Eligibility.new(award_amount: 0, itt_academic_year: academic_year)).to be_valid
end
it "validates that the award_amount is less than £7,500 when amending a claim" do
- 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)
+ expect(Policies::EarlyCareerPayments::Eligibility.new(teacher_reference_number: "1234567", award_amount: 7_501, itt_academic_year: academic_year)).not_to be_valid(:amendment)
+ expect(Policies::EarlyCareerPayments::Eligibility.new(teacher_reference_number: "1234567", award_amount: 7_500, itt_academic_year: academic_year)).to be_valid(:amendment)
+ expect(Policies::EarlyCareerPayments::Eligibility.new(teacher_reference_number: "1234567", award_amount: 7_499, itt_academic_year: academic_year)).to be_valid(:amendment)
end
end
end
diff --git a/spec/models/policies/levelling_up_premium_payments/dqt_record_spec.rb b/spec/models/policies/levelling_up_premium_payments/dqt_record_spec.rb
index dbdcb9e24f..e84cccaaa9 100644
--- a/spec/models/policies/levelling_up_premium_payments/dqt_record_spec.rb
+++ b/spec/models/policies/levelling_up_premium_payments/dqt_record_spec.rb
@@ -289,7 +289,7 @@
let(:eligible_subjects) { [:computing] }
before do
- allow(JourneySubjectEligibilityChecker).to receive(:fixed_lup_subject_symbols)
+ allow(Policies::LevellingUpPremiumPayments).to receive(:fixed_subject_symbols)
.and_return(eligible_subjects)
end
@@ -340,8 +340,9 @@
describe "#itt_academic_year_for_claim" do
before do
- allow(JourneySubjectEligibilityChecker).to receive(:new)
- .and_return(double(selectable_itt_years_for_claim_year: eligible_years))
+ allow(Policies::LevellingUpPremiumPayments).to(
+ receive(:selectable_itt_years_for_claim_year).and_return(eligible_years)
+ )
end
let(:record) do