diff --git a/app/helpers/admin/claims_helper.rb b/app/helpers/admin/claims_helper.rb
index be8c73a699..e91e6ff0b6 100644
--- a/app/helpers/admin/claims_helper.rb
+++ b/app/helpers/admin/claims_helper.rb
@@ -74,7 +74,7 @@ def admin_decision_details(decision)
def rejected_reasons_list(decision)
decision.selected_rejected_reasons
.sort_by { |k| Decision::REJECTED_REASONS.index(k) }
- .map { |reason| t("admin.decision.rejected_reasons.#{reason}") }
+ .map { |reason| t("#{decision.policy.locale_key}.admin.decision.rejected_reasons.#{reason}") }
.join(", ")
end
diff --git a/app/models/decision.rb b/app/models/decision.rb
index 46e798e351..386ee637bd 100644
--- a/app/models/decision.rb
+++ b/app/models/decision.rb
@@ -2,18 +2,11 @@ class Decision < ApplicationRecord
belongs_to :claim
belongs_to :created_by, class_name: "DfeSignIn::User", optional: true
- # NOTE: remember en.yml -> admin.decision.rejected_reasons
- REJECTED_REASONS = [
- :ineligible_subject,
- :ineligible_year,
- :ineligible_school,
- :ineligible_qualification,
- :induction,
- :no_qts_or_qtls,
- :duplicate,
- :no_response,
- :other
- ]
+ delegate :policy, to: :claim
+
+ REJECTED_REASONS = Policies.all.flat_map do |policy|
+ policy::ADMIN_DECISION_REJECTED_REASONS
+ end.uniq
store_accessor :rejected_reasons, *REJECTED_REASONS, prefix: true
@@ -37,9 +30,7 @@ class Decision < ApplicationRecord
}
def self.rejected_reasons_for(policy)
- REJECTED_REASONS.dup.tap do |reasons|
- reasons.delete(:induction) unless policy == Policies::EarlyCareerPayments
- end
+ policy::ADMIN_DECISION_REJECTED_REASONS
end
def readonly?
@@ -48,7 +39,7 @@ def readonly?
end
def rejected_reasons_hash
- REJECTED_REASONS.reduce({}) do |memo, reason|
+ policy::ADMIN_DECISION_REJECTED_REASONS.reduce({}) do |memo, reason|
memo.merge("reason_#{reason}": public_send(:"rejected_reasons_#{reason}") || "0")
end
end
diff --git a/app/models/policies/early_career_payments.rb b/app/models/policies/early_career_payments.rb
index 1f6569aa95..7e8e9a2ca9 100644
--- a/app/models/policies/early_career_payments.rb
+++ b/app/models/policies/early_career_payments.rb
@@ -40,6 +40,19 @@ module EarlyCareerPayments
# Percentage of claims to QA
MIN_QA_THRESHOLD = 10
+ # Options shown to admins when rejecting a claim
+ ADMIN_DECISION_REJECTED_REASONS = [
+ :ineligible_subject,
+ :ineligible_year,
+ :ineligible_school,
+ :ineligible_qualification,
+ :induction,
+ :no_qts_or_qtls,
+ :duplicate,
+ :no_response,
+ :other
+ ]
+
def eligibility_page_url
"https://www.gov.uk/guidance/early-career-payments-guidance-for-teachers-and-schools"
end
diff --git a/app/models/policies/further_education_payments.rb b/app/models/policies/further_education_payments.rb
index a879b6241b..93b240015a 100644
--- a/app/models/policies/further_education_payments.rb
+++ b/app/models/policies/further_education_payments.rb
@@ -8,6 +8,15 @@ module FurtherEducationPayments
URL_SPREADSHEET_ELIGIBLE_PROVIDERS = "https://assets.publishing.service.gov.uk/media/667300fe64e554df3bd0db92/List_of_eligible_FE_providers_and_payment_value_for_levelling_up_premium.xlsx".freeze
+ # Options shown to admins when rejecting a claim
+ ADMIN_DECISION_REJECTED_REASONS = [
+ # FIXME RL: this `placeholder` is required to make the
+ # `spec/models/policies/further_education_payments/claim_personal_data_scrubber_spec.rb`
+ # test pass. Once we add a real rejection reason we can remove this
+ # placeholder. Figured this was better than removing the test!
+ :placeholder
+ ]
+
# TODO: This is needed once the reply-to email address has been added to Gov Notify
def notify_reply_to_id
nil
diff --git a/app/models/policies/international_relocation_payments.rb b/app/models/policies/international_relocation_payments.rb
index 75641260c1..b435637a19 100644
--- a/app/models/policies/international_relocation_payments.rb
+++ b/app/models/policies/international_relocation_payments.rb
@@ -9,6 +9,18 @@ module InternationalRelocationPayments
# Percentage of claims to QA
MIN_QA_THRESHOLD = 100
+ # Options shown to admins when rejecting a claim
+ ADMIN_DECISION_REJECTED_REASONS = [
+ :duplicate,
+ :ineligible_school,
+ :invalid_bank_details,
+ :ineligible_visa_or_entry_date,
+ :ineligible_employment_terms,
+ :no_response_from_school,
+ :suspected_fraud,
+ :information_mismatch_new_details_needed
+ ]
+
# NOTE RL: currently IRP only has a single reply to address, so notify
# doesn't show the address id
def notify_reply_to_id
diff --git a/app/models/policies/levelling_up_premium_payments.rb b/app/models/policies/levelling_up_premium_payments.rb
index 69837d6308..23c60af821 100644
--- a/app/models/policies/levelling_up_premium_payments.rb
+++ b/app/models/policies/levelling_up_premium_payments.rb
@@ -30,6 +30,18 @@ module LevellingUpPremiumPayments
# Percentage of claims to QA
MIN_QA_THRESHOLD = 10
+ # Options shown to admins when rejecting a claim
+ ADMIN_DECISION_REJECTED_REASONS = [
+ :ineligible_subject,
+ :ineligible_year,
+ :ineligible_school,
+ :ineligible_qualification,
+ :no_qts_or_qtls,
+ :duplicate,
+ :no_response,
+ :other
+ ]
+
def notify_reply_to_id
"03ece7eb-2a5b-461b-9c91-6630d0051aa6"
end
diff --git a/app/models/policies/student_loans.rb b/app/models/policies/student_loans.rb
index 71006ed7d9..004b6e6242 100644
--- a/app/models/policies/student_loans.rb
+++ b/app/models/policies/student_loans.rb
@@ -40,6 +40,18 @@ module StudentLoans
# Percentage of claims to QA
MIN_QA_THRESHOLD = 10
+ # Options shown to admins when rejecting a claim
+ ADMIN_DECISION_REJECTED_REASONS = [
+ :ineligible_subject,
+ :ineligible_year,
+ :ineligible_school,
+ :ineligible_qualification,
+ :no_qts_or_qtls,
+ :duplicate,
+ :no_response,
+ :other
+ ]
+
def eligibility_page_url
"https://www.gov.uk/guidance/teachers-claim-back-your-student-loan-repayments"
end
diff --git a/app/views/admin/decisions/_decision_form.html.erb b/app/views/admin/decisions/_decision_form.html.erb
index 610bd3bded..ffe191fdcf 100644
--- a/app/views/admin/decisions/_decision_form.html.erb
+++ b/app/views/admin/decisions/_decision_form.html.erb
@@ -70,7 +70,7 @@
<%= form.hidden_field reason_prefixed, value: false %>
<%= form.check_box reason_prefixed, class: "govuk-checkboxes__input subject", id: reason_prefixed %>
- <%= form.label reason_prefixed, t("admin.decision.rejected_reasons.#{reason}"), class: "govuk-label govuk-checkboxes__label", for: reason_prefixed %>
+ <%= form.label reason_prefixed, t("#{claim.policy.locale_key}.admin.decision.rejected_reasons.#{reason}"), class: "govuk-label govuk-checkboxes__label", for: reason_prefixed %>
<% end %>
diff --git a/config/locales/en.yml b/config/locales/en.yml
index 9e63f7e170..baf0208d95 100644
--- a/config/locales/en.yml
+++ b/config/locales/en.yml
@@ -128,16 +128,6 @@ en:
notes: "Notes"
created_by: "Created by"
reasons: Reasons
- rejected_reasons:
- ineligible_subject: Ineligible subject
- ineligible_year: Ineligible year
- ineligible_school: Ineligible school
- ineligible_qualification: Ineligible qualification
- induction: Induction - ECP only
- no_qts_or_qtls: No QTS or QTLS
- duplicate: Duplicate
- no_response: No response
- other: Other
duplicate_attributes_message:
one: Details in this claim match another %{policy} claim
other: Details in this claim match other %{policy} claims
@@ -389,6 +379,16 @@ en:
information_provided_further_details_link_text: claiming back your student loan repayments (opens in new tab)
admin:
claim_school: "Claim school"
+ decision:
+ rejected_reasons:
+ ineligible_subject: Ineligible subject
+ ineligible_year: Ineligible year
+ ineligible_school: Ineligible school
+ ineligible_qualification: Ineligible qualification
+ no_qts_or_qtls: No QTS or QTLS
+ duplicate: Duplicate
+ no_response: No response
+ other: Other
subjects_taught: "Subjects taught"
had_leadership_position: "Had leadership position?"
mostly_performed_leadership_duties: "Mostly performed leadership duties?"
@@ -624,6 +624,17 @@ en:
employed_as_supply_teacher: "Employed as a supply teacher?"
nqt_in_academic_year_after_itt: "Teaching as a qualified teacher?"
induction_completed: "Has completed induction as an early-career teacher?"
+ decision:
+ rejected_reasons:
+ ineligible_subject: Ineligible subject
+ ineligible_year: Ineligible year
+ ineligible_school: Ineligible school
+ ineligible_qualification: Ineligible qualification
+ induction: Induction - ECP only
+ no_qts_or_qtls: No QTS or QTLS
+ duplicate: Duplicate
+ no_response: No response
+ other: Other
task_questions:
employment:
title: "Does the claimant’s current school match the above information from their claim?"
@@ -772,6 +783,16 @@ en:
policy_short_name: "International Relocation Payments"
policy_acronym: "IRP"
admin:
+ decision:
+ rejected_reasons:
+ duplicate: Duplicate application
+ ineligible_school: Ineligible school
+ invalid_bank_details: Invalid bank details
+ ineligible_visa_or_entry_date: "Visa/entry date ineligible"
+ ineligible_employment_terms: Ineligible employment terms
+ no_response_from_school: No response from school
+ suspected_fraud: Suspected fraud
+ information_mismatch_new_details_needed: "Information mismatch - new details needed"
eligibility_answers:
nationality: "Nationality"
passport_number: "Passport number"
diff --git a/spec/factories/decisions.rb b/spec/factories/decisions.rb
index dfc247ecb7..49310acd7a 100644
--- a/spec/factories/decisions.rb
+++ b/spec/factories/decisions.rb
@@ -9,7 +9,7 @@
trait :rejected do
result { :rejected }
- rejected_reasons_ineligible_subject { "1" }
+ rejected_reasons { {policy::ADMIN_DECISION_REJECTED_REASONS.first => "1"} }
end
trait :with_notes do
diff --git a/spec/helpers/claim_mailer_helper_spec.rb b/spec/helpers/claim_mailer_helper_spec.rb
index 3631c102d7..d6d92f61d8 100644
--- a/spec/helpers/claim_mailer_helper_spec.rb
+++ b/spec/helpers/claim_mailer_helper_spec.rb
@@ -3,7 +3,8 @@
describe ClaimMailerHelper do
describe ".rejected_reasons_personalisation" do
subject { rejected_reasons_personalisation(decision.rejected_reasons_hash) }
- let(:decision) { create(:decision, :rejected, :with_notes, **rejected_reasons) }
+ let(:claim) { create(:claim, policy: Policies::EarlyCareerPayments) }
+ let(:decision) { create(:decision, :rejected, :with_notes, claim: claim, **rejected_reasons) }
context "with rejected reasons that don't include 'other'" do
let(:rejected_reasons) do
diff --git a/spec/mailers/claim_mailer_spec.rb b/spec/mailers/claim_mailer_spec.rb
index bafaae24dd..6fcf9c3b2c 100644
--- a/spec/mailers/claim_mailer_spec.rb
+++ b/spec/mailers/claim_mailer_spec.rb
@@ -11,7 +11,7 @@ class SomePolicy; end
end
it "sets the GOV.UK Notify reply_to_id according to the policy" do
- expect(mail["reply_to_id"].value).to eql(policy.notify_reply_to_id)
+ expect(mail["reply_to_id"]&.value).to eql(policy.notify_reply_to_id)
end
it "mentions the type of claim in the subject and body" do
@@ -37,7 +37,7 @@ class SomePolicy; end
end
it "sets the GOV.UK Notify reply_to_id according to the policy" do
- expect(mail["reply_to_id"].value).to eql(policy.notify_reply_to_id)
+ expect(mail["reply_to_id"]&.value).to eql(policy.notify_reply_to_id)
end
it "includes a personalisation key for claim reference (ref_number)" do
@@ -57,7 +57,7 @@ class SomePolicy; end
end
# Characteristics common to all policies
- [Policies::EarlyCareerPayments, Policies::StudentLoans, Policies::LevellingUpPremiumPayments].each do |policy|
+ [Policies::EarlyCareerPayments, Policies::StudentLoans, Policies::LevellingUpPremiumPayments, Policies::InternationalRelocationPayments].each do |policy|
context "with a #{policy} claim" do
let!(:journey_configuration) { create(:journey_configuration, policy.to_s.underscore) }
@@ -84,6 +84,12 @@ class SomePolicy; end
expect(mail.template_id).to eq "f9e39fcd-301a-4427-9159-6831fd484e39"
end
end
+
+ context "when InternationalRelocationPayments", if: policy == Policies::InternationalRelocationPayments do
+ it "uses the correct template" do
+ expect(mail.template_id).to eq "316d6c56-2354-4cb7-9d1d-3b61bc7e8c59"
+ end
+ end
end
describe "#approved" do
@@ -109,6 +115,12 @@ class SomePolicy; end
expect(mail.template_id).to eq "2032be01-6aee-4a1a-81ce-cf91e09de8d7"
end
end
+
+ context "when InternationalRelocationPayments", if: policy == Policies::InternationalRelocationPayments do
+ it "uses the correct template" do
+ expect(mail.template_id).to eq "5cf5287f-3bdf-4d0b-b999-b61987b9c39f"
+ end
+ end
end
describe "#rejected" do
@@ -126,19 +138,6 @@ class SomePolicy; end
current_financial_year: (policy == Policies::StudentLoans) ? Policies::StudentLoans.current_financial_year : ""
}
end
- let(:expected_rejected_reasons_keys) do
- {
- reason_ineligible_subject: "yes",
- reason_ineligible_year: "no",
- reason_ineligible_school: "no",
- reason_ineligible_qualification: "no",
- reason_induction: "no",
- reason_no_qts_or_qtls: "no",
- reason_duplicate: "no",
- reason_no_response: "no",
- reason_other: "no"
- }
- end
let(:all_expected_keys) { expected_common_keys.merge(expected_rejected_reasons_keys) }
it "uses the correct template" do
@@ -161,18 +160,77 @@ class SomePolicy; end
context "when EarlyCareerPayments", if: policy == Policies::EarlyCareerPayments do
let(:expected_template_id) { "b78ffea4-a3d7-4c4a-b0f7-066744c6e79f" }
+ let(:expected_rejected_reasons_keys) do
+ {
+ reason_ineligible_subject: "yes",
+ reason_ineligible_year: "no",
+ reason_ineligible_school: "no",
+ reason_ineligible_qualification: "no",
+ reason_induction: "no",
+ reason_no_qts_or_qtls: "no",
+ reason_duplicate: "no",
+ reason_no_response: "no",
+ reason_other: "no"
+ }
+ end
+
include_examples "template id and personalisation keys"
end
context "when LevellingUpPremiumPayments", if: policy == Policies::LevellingUpPremiumPayments do
let(:expected_template_id) { "c20e8d85-ef71-4395-8f8b-90fcbd824b86" }
+ let(:expected_rejected_reasons_keys) do
+ {
+ reason_ineligible_subject: "yes",
+ reason_ineligible_year: "no",
+ reason_ineligible_school: "no",
+ reason_ineligible_qualification: "no",
+ reason_no_qts_or_qtls: "no",
+ reason_duplicate: "no",
+ reason_no_response: "no",
+ reason_other: "no"
+ }
+ end
+
include_examples "template id and personalisation keys"
end
context "when StudentLoans", if: policy == Policies::StudentLoans do
let(:expected_template_id) { "f719237d-6b2a-42d6-98f2-3d5b6585f32b" }
+ let(:expected_rejected_reasons_keys) do
+ {
+ reason_ineligible_subject: "yes",
+ reason_ineligible_year: "no",
+ reason_ineligible_school: "no",
+ reason_ineligible_qualification: "no",
+ reason_no_qts_or_qtls: "no",
+ reason_duplicate: "no",
+ reason_no_response: "no",
+ reason_other: "no"
+ }
+ end
+
+ include_examples "template id and personalisation keys"
+ end
+
+ context "when InternationalRelocationPayments", if: policy == Policies::InternationalRelocationPayments do
+ let(:expected_template_id) { "1edc468c-a1bf-4bea-bb79-042740cd8547" }
+
+ let(:expected_rejected_reasons_keys) do
+ {
+ reason_duplicate: "yes",
+ reason_ineligible_school: "no",
+ reason_invalid_bank_details: "no",
+ reason_ineligible_visa_or_entry_date: "no",
+ reason_ineligible_employment_terms: "no",
+ reason_no_response_from_school: "no",
+ reason_suspected_fraud: "no",
+ reason_information_mismatch_new_details_needed: "no"
+ }
+ end
+
include_examples "template id and personalisation keys"
end
end
diff --git a/spec/models/decision_spec.rb b/spec/models/decision_spec.rb
index 6b691dbfea..2c91d0f168 100644
--- a/spec/models/decision_spec.rb
+++ b/spec/models/decision_spec.rb
@@ -148,29 +148,79 @@
describe "#rejected_reasons_hash" do
subject { decision.rejected_reasons_hash }
- let(:decision) { create(:decision, :rejected, **rejected_reasons) }
- let(:rejected_reasons) do
- {
- rejected_reasons_ineligible_subject: "1",
- rejected_reasons_no_qts_or_qtls: "1"
- }
+ let(:decision) { create(:decision, :rejected, claim: claim, **rejected_reasons) }
+
+ context "with an ECP claim" do
+ let(:claim) { create(:claim, policy: Policies::EarlyCareerPayments) }
+
+ let(:rejected_reasons) do
+ {
+ rejected_reasons_ineligible_subject: "1",
+ rejected_reasons_no_qts_or_qtls: "1"
+ }
+ end
+
+ it do
+ is_expected.to eq(
+ reason_ineligible_subject: "1",
+ reason_ineligible_year: "0",
+ reason_ineligible_school: "0",
+ reason_ineligible_qualification: "0",
+ reason_no_qts_or_qtls: "1",
+ reason_duplicate: "0",
+ reason_induction: "0",
+ reason_no_response: "0",
+ reason_other: "0"
+ )
+ end
end
- let(:expected_hash) do
- {
- reason_ineligible_subject: "1",
- reason_ineligible_year: "0",
- reason_ineligible_school: "0",
- reason_ineligible_qualification: "0",
- reason_no_qts_or_qtls: "1",
- reason_duplicate: "0",
- reason_induction: "0",
- reason_no_response: "0",
- reason_other: "0"
- }
+
+ context "with an LUP claim" do
+ let(:claim) { create(:claim, policy: Policies::LevellingUpPremiumPayments) }
+
+ let(:rejected_reasons) do
+ {
+ rejected_reasons_ineligible_subject: "1",
+ rejected_reasons_no_qts_or_qtls: "1"
+ }
+ end
+
+ it do
+ is_expected.to eq(
+ reason_ineligible_subject: "1",
+ reason_ineligible_year: "0",
+ reason_ineligible_school: "0",
+ reason_ineligible_qualification: "0",
+ reason_no_qts_or_qtls: "1",
+ reason_duplicate: "0",
+ reason_no_response: "0",
+ reason_other: "0"
+ )
+ end
end
- it "returns the complete hash of rejected reasons" do
- is_expected.to eq(expected_hash)
+ context "with a TSLR claim" do
+ let(:rejected_reasons) do
+ {
+ rejected_reasons_ineligible_subject: "1",
+ rejected_reasons_no_qts_or_qtls: "1"
+ }
+ end
+
+ let(:claim) { create(:claim, policy: Policies::StudentLoans) }
+
+ it do
+ is_expected.to eq(
+ reason_ineligible_subject: "1",
+ reason_ineligible_year: "0",
+ reason_ineligible_school: "0",
+ reason_ineligible_qualification: "0",
+ reason_no_qts_or_qtls: "1",
+ reason_duplicate: "0",
+ reason_no_response: "0",
+ reason_other: "0"
+ )
+ end
end
end