Skip to content

Commit

Permalink
Move selectable_subject_symbols into the journey.
Browse files Browse the repository at this point in the history
There was a lot of duplicated business rules in this method.
We were explicity checking for `nqt_in_academic_year_after_itt`, and if
it was absent we were falling back to only the lup subjects. The ECP
policy is ineligible for non `nqt_in_academic_year_after_itt` claims so
it will be filtered out when we check for
`potentially_still_eligible_policies`.
We returned an empty array if the `current_academic_year` was outside
the lup policy dates, however the LUP#subject_symbols method already
returns an empty array of available subjects for years outside the
policy.

There's some weirdness in the
`AdditionalPaymentsForTeaching.selectable_subject_symbols` method. If
we're dealing with a trainee teacher, we return a hard coded list of
subjects, however trainee teachers won't be eligible as the
`EligibilityCheckable#common_ineligible_attributes?` checks if the
claimant is a trainee teacher, and is thus ineligible. It seems weird to
return a list of subjects if the claimant is ineligible. This was the
existing behaviour so I've kept it in place but this likely needs
revisiting.
  • Loading branch information
rjlynch committed Dec 11, 2024
1 parent 2afe1bf commit f94942a
Show file tree
Hide file tree
Showing 20 changed files with 593 additions and 276 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down
6 changes: 5 additions & 1 deletion app/models/academic_year.rb
Original file line number Diff line number Diff line change
Expand Up @@ -107,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}"
Expand Down
19 changes: 14 additions & 5 deletions app/models/concerns/eligibility_checkable.rb
Original file line number Diff line number Diff line change
Expand Up @@ -49,7 +49,15 @@ 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?
[
indicated_ineligible_school?,
trainee_teacher?,
supply_teacher_lacking_either_long_contract_or_direct_employment?,
poor_performance?,
no_selectable_subjects?,
ineligible_cohort?,
insufficient_teaching?
].any?
end

def indicated_ineligible_school?
Expand All @@ -65,12 +73,13 @@ 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

Expand Down
20 changes: 20 additions & 0 deletions app/models/journeys/additional_payments_for_teaching.rb
Original file line number Diff line number Diff line change
Expand Up @@ -42,5 +42,25 @@ def set_a_reminder?(itt_academic_year:, policy:)
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?(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
Policies::LevellingUpPremiumPayments.fixed_subject_symbols
else
[]
end
end
end
end
Original file line number Diff line number Diff line change
Expand Up @@ -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}")
Expand All @@ -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
Expand Down
8 changes: 8 additions & 0 deletions app/models/journeys/eligibility_checker.rb
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down
2 changes: 1 addition & 1 deletion app/models/journeys/page_sequence.rb
Original file line number Diff line number Diff line change
Expand Up @@ -104,7 +104,7 @@ def handle_trainee_teacher
@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
if answers.eligible_itt_subject.to_sym.in? Policies::LevellingUpPremiumPayments.fixed_subject_symbols
"future-eligibility"
else
"eligible-degree-subject"
Expand Down
35 changes: 35 additions & 0 deletions app/models/policies/early_career_payments.rb
Original file line number Diff line number Diff line change
Expand Up @@ -110,6 +110,29 @@ 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)
Expand All @@ -134,5 +157,17 @@ def subject_symbols(claim_year:, itt_year:)
[]
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
end
end
7 changes: 4 additions & 3 deletions app/models/policies/early_career_payments/dqt_record.rb
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -47,8 +47,10 @@ def itt_subject_eligible_now?
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))
EarlyCareerPayments.current_subject_symbols(
claim_year: claim_year,
itt_year: itt_academic_year
).include?(itt_subject.to_sym)
end

def specific_ineligible_attributes?
Expand All @@ -60,8 +62,10 @@ def itt_subject_ineligible_now_and_in_the_future?
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))
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?
Expand All @@ -73,8 +77,10 @@ def itt_subject_eligible_later?
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))
EarlyCareerPayments.future_subject_symbols(
claim_year: claim_year,
itt_year: itt_academic_year
).include?(itt_subject.to_sym)
end

# TODO: Is this used anywhere?
Expand All @@ -94,9 +100,10 @@ def itt_subject_other_than_those_eligible_now_or_in_the_future?
# 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))
EarlyCareerPayments.current_and_future_subject_symbols(
claim_year: claim_year,
itt_year: itt_academic_year
).exclude?(itt_subject_symbol)
end
end
end
Expand Down
41 changes: 40 additions & 1 deletion app/models/policies/levelling_up_premium_payments.rb
Original file line number Diff line number Diff line change
Expand Up @@ -100,16 +100,55 @@ 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 fixed_subject_symbols
[:chemistry, :computing, :mathematics, :physics]
end

def subject_symbols(claim_year:, itt_year:)
return [] unless (POLICY_START_YEAR..POLICY_END_YEAR).cover?(claim_year)

previous_five_years = (claim_year - 5)...claim_year

if previous_five_years.cover?(itt_year)
[:chemistry, :computing, :mathematics, :physics]
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
end
end
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,7 @@ def indicated_ineligible_itt_subject?

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)
eligible_itt_subject.present? && !eligible_itt_subject.to_sym.in?(policy.fixed_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))
Expand Down
4 changes: 2 additions & 2 deletions lib/ineligibility_reason_checker.rb
Original file line number Diff line number Diff line change
Expand Up @@ -154,10 +154,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?
Expand Down
22 changes: 7 additions & 15 deletions lib/journey_subject_eligibility_checker.rb
Original file line number Diff line number Diff line change
Expand Up @@ -41,27 +41,14 @@ 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

# FIXME RL - should be able to delete all the methods using this
def current_and_future_subject_symbols(policy)
(current_subject_symbols(policy) + future_subject_symbols(policy)).uniq
end
Expand All @@ -70,7 +57,11 @@ 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)
subject_symbols(
policy: policy,
claim_year: @claim_year,
itt_year: @itt_year
)
end
end

Expand All @@ -92,6 +83,7 @@ def selectable_subject_symbols(answers)

private

# Move this
def potentially_still_eligible_policies(answers)
Journeys::AdditionalPaymentsForTeaching::POLICIES.select do |policy|
policy::PolicyEligibilityChecker.new(answers: answers).status != :ineligible
Expand Down
Loading

0 comments on commit f94942a

Please sign in to comment.