From a79926730dd8ae49860ecd76c4c1d1e49771cd4f Mon Sep 17 00:00:00 2001 From: Richard Lynch Date: Thu, 26 Sep 2024 15:16:31 +0100 Subject: [PATCH] Add task if provider / claimant details match If the claimant and provider have matching details (name or email) we want to raise an admin task for ops to check that the claimant isn't trying to approve their own claim. --- app/models/claim_checking_tasks.rb | 1 + .../admin_tasks_presenter.rb | 9 ++ .../claim_checking_tasks.rb | 1 + .../further_education_payments/eligibility.rb | 35 +++++++ app/models/task.rb | 1 + .../admin/tasks/provider_details.html.erb | 27 +++++ config/locales/en.yml | 4 + ...s_further_education_payments_claim_spec.rb | 98 +++++++++++++++++++ .../claim_checking_tasks_spec.rb | 35 ++++++- 9 files changed, 209 insertions(+), 2 deletions(-) create mode 100644 app/views/admin/tasks/provider_details.html.erb create mode 100644 spec/features/admin/admin_checks_further_education_payments_claim_spec.rb diff --git a/app/models/claim_checking_tasks.rb b/app/models/claim_checking_tasks.rb index 5a5e2de33e..ada338d5bb 100644 --- a/app/models/claim_checking_tasks.rb +++ b/app/models/claim_checking_tasks.rb @@ -38,6 +38,7 @@ def applicable_task_names task_names.delete("subject") task_names.delete("teaching_hours") task_names.delete("provider_verification") + task_names.delete("provider_details") end end end diff --git a/app/models/policies/further_education_payments/admin_tasks_presenter.rb b/app/models/policies/further_education_payments/admin_tasks_presenter.rb index 9294ddfd9b..ae1e84c429 100644 --- a/app/models/policies/further_education_payments/admin_tasks_presenter.rb +++ b/app/models/policies/further_education_payments/admin_tasks_presenter.rb @@ -40,6 +40,15 @@ def student_loan_plan ] end + def provider_details + [ + ["Provider name", claim.eligibility.provider_full_name], + ["Provider email", claim.eligibility.provider_email], + ["Claimant name", claim.full_name], + ["Claimant email", claim.email_address] + ] + end + private def verifier diff --git a/app/models/policies/further_education_payments/claim_checking_tasks.rb b/app/models/policies/further_education_payments/claim_checking_tasks.rb index f6159a4ff5..1fb2e58dd6 100644 --- a/app/models/policies/further_education_payments/claim_checking_tasks.rb +++ b/app/models/policies/further_education_payments/claim_checking_tasks.rb @@ -16,6 +16,7 @@ def applicable_task_names tasks << "identity_confirmation" tasks << "provider_verification" + tasks << "provider_details" if claim.eligibility.provider_and_claimant_details_match? tasks << "employment" if claim.eligibility.teacher_reference_number.present? tasks << "student_loan_plan" if claim.submitted_without_slc_data? tasks << "payroll_details" if claim.must_manually_validate_bank_details? diff --git a/app/models/policies/further_education_payments/eligibility.rb b/app/models/policies/further_education_payments/eligibility.rb index 90be4cc547..eac6b0dcca 100644 --- a/app/models/policies/further_education_payments/eligibility.rb +++ b/app/models/policies/further_education_payments/eligibility.rb @@ -70,6 +70,41 @@ def permanent_contract? def verified? verification.present? end + + def provider_and_claimant_details_match? + provider_and_claimant_names_match? || provider_and_claimant_emails_match? + end + + def provider_full_name + "#{provider_first_name} #{provider_last_name}" + end + + def provider_email + verification.dig("verifier", "email") + end + + private + + def provider_and_claimant_names_match? + return false unless verified? + + provider_first_name&.downcase == claim.first_name.downcase && + provider_last_name&.downcase == claim.surname.downcase + end + + def provider_and_claimant_emails_match? + return false unless verified? + + provider_email.downcase == claim.email_address.downcase + end + + def provider_first_name + verification.dig("verifier", "first_name") + end + + def provider_last_name + verification.dig("verifier", "last_name") + end end end end diff --git a/app/models/task.rb b/app/models/task.rb index 8cfdd1e049..eac6d3c426 100644 --- a/app/models/task.rb +++ b/app/models/task.rb @@ -11,6 +11,7 @@ class Task < ApplicationRecord previous_payment identity_confirmation provider_verification + provider_details visa arrival_date previous_residency diff --git a/app/views/admin/tasks/provider_details.html.erb b/app/views/admin/tasks/provider_details.html.erb new file mode 100644 index 0000000000..d6f4cde036 --- /dev/null +++ b/app/views/admin/tasks/provider_details.html.erb @@ -0,0 +1,27 @@ +<% content_for(:page_title) { page_title("Claim #{@claim.reference} provider details check for #{@claim.policy.short_name}") } %> + +<% content_for :back_link do %> + <%= govuk_back_link href: admin_claim_tasks_path(@claim) %> +<% end %> + +<%= render "shared/error_summary", instance: @task, errored_field_id_overrides: { "passed": "task_passed_true" } if @task.errors.any? %> + +
+ <%= render claim_summary_view, claim: @claim, heading: "Subject check" %> + +
+

<%= @current_task_name.humanize %>

+ + <%= render "admin/claims/answers", answers: @tasks_presenter.provider_details %> +
+ +
+ <% if !@task.passed.nil? %> + <%= render "task_outcome", task: @task %> + <% else %> + <%= render "form", task_name: "provider_details", claim: @claim %> + <% end %> + + <%= render partial: "admin/task_pagination" %> +
+
diff --git a/config/locales/en.yml b/config/locales/en.yml index 4ebdac63b8..95f2d5bf89 100644 --- a/config/locales/en.yml +++ b/config/locales/en.yml @@ -149,6 +149,8 @@ en: title: "Confirm the claimant made the claim" provider_verification: title: "Confirm the provider has responded and verified the claimant's information" + provider_details: + title: "Check the provider details" payroll_gender: title: "How is the claimant’s gender recorded for payroll purposes?" hint: "The claimant answered ‘don’t know’ to the question ‘how is your gender recorded on your employer’s payroll system?’" @@ -933,6 +935,8 @@ en: claimant_answers: true: "Yes" false: "No" + provider_details: + title: "Is the claim still valid even though the claimant and provider have matching details?" student_loan_plan: title: "Does the claimant’s student loan plan match the information we hold about their loan?" forms: diff --git a/spec/features/admin/admin_checks_further_education_payments_claim_spec.rb b/spec/features/admin/admin_checks_further_education_payments_claim_spec.rb new file mode 100644 index 0000000000..52bc8e36c0 --- /dev/null +++ b/spec/features/admin/admin_checks_further_education_payments_claim_spec.rb @@ -0,0 +1,98 @@ +require "rails_helper" + +RSpec.feature "Admin checks a further education payments claim" do + before do + sign_in_as_service_operator + end + + context "when the claim has a claimant and provider with the same name" do + it "requires the admin to check for provider fraud" do + claim = create( + :claim, + :submitted, + first_name: "Walter", + middle_name: "Seymour", + surname: "Skinner", + email_address: "w.s.skinner@example.com", + policy: Policies::FurtherEducationPayments, + eligibility_attributes: { + verification: { + verifier: { + first_name: "Walter", + last_name: "Skinner", + email: "w.s.skinner@springfield-elementary.edu" + } + } + } + ) + + visit admin_claim_tasks_path(claim) + + expect(page).to have_content("Check the provider details") + + click_on "Check the provider details" + + expect(page).to have_content( + "Is the claim still valid even though the claimant and provider have matching details?" + ) + end + end + + context "when the claim has a claimant and provider with the same email" do + it "requires the admin to check for provider fraud" do + claim = create( + :claim, + :submitted, + first_name: "Armin", + surname: "Tamzarian", + email_address: "w.s.skinner@springfield-elementary.edu", + policy: Policies::FurtherEducationPayments, + eligibility_attributes: { + verification: { + verifier: { + first_name: "Walter", + last_name: "Skinner", + email: "w.s.skinner@springfield-elementary.edu" + } + } + } + ) + + visit admin_claim_tasks_path(claim) + + expect(page).to have_content("Check the provider details") + + click_on "Check the provider details" + + expect(page).to have_content( + "Is the claim still valid even though the claimant and provider have matching details?" + ) + end + end + + context "when the claim has a claimant and provider with different details" do + it "doesn't require the admin check for provider fraud" do + claim = create( + :claim, + :submitted, + first_name: "Edna", + surname: "Krabappel", + email_address: "e.krabappel@springfield-elementary.edu", + policy: Policies::FurtherEducationPayments, + eligibility_attributes: { + verification: { + verifier: { + first_name: "Walter", + last_name: "Skinner", + email: "w.s.skinner@springfield-elementary.edu" + } + } + } + ) + + visit admin_claim_tasks_path(claim) + + expect(page).not_to have_content("Check the provider details") + end + end +end diff --git a/spec/models/policies/further_education_payments/claim_checking_tasks_spec.rb b/spec/models/policies/further_education_payments/claim_checking_tasks_spec.rb index 422604e0ad..e0dfdfd1a4 100644 --- a/spec/models/policies/further_education_payments/claim_checking_tasks_spec.rb +++ b/spec/models/policies/further_education_payments/claim_checking_tasks_spec.rb @@ -8,11 +8,21 @@ let(:teacher_reference_number) { "1234567" } let(:matching_claims) { Claim.none } let(:hmrc_bank_validation_succeeded) { true } + let(:claimant_first_name) { "Edna" } + let(:claimant_surname) { "Krabappel" } + let(:claimant_email_address) { "e.krabappel@springfield-elementary.edu" } let(:eligibility) do build( :further_education_payments_eligibility, - teacher_reference_number: teacher_reference_number + teacher_reference_number: teacher_reference_number, + verification: { + verifier: { + first_name: "Walter", + last_name: "Skinner", + email: "w.s.skinner@springfield-elementary.edu" + } + } ) end @@ -22,7 +32,10 @@ policy: Policies::FurtherEducationPayments, payroll_gender: payroll_gender, hmrc_bank_validation_succeeded: hmrc_bank_validation_succeeded, - eligibility: eligibility + eligibility: eligibility, + first_name: claimant_first_name, + surname: claimant_surname, + email_address: claimant_email_address ) end @@ -83,5 +96,23 @@ it { is_expected.not_to include("payroll_details") } it { is_expected.to include(*invariant_tasks) } end + + context "when the claimant and provider names match" do + let(:claimant_first_name) { "Walter" } + let(:claimant_surname) { "Skinner" } + it { is_expected.to include("provider_details") } + it { is_expected.to include(*invariant_tasks) } + end + + context "when the claimant and provider emails match" do + let(:claimant_email_address) { "w.s.skinner@springfield-elementary.edu" } + it { is_expected.to include("provider_details") } + it { is_expected.to include(*invariant_tasks) } + end + + context "when the claim and provider details are different" do + it { is_expected.not_to include("provider_details") } + it { is_expected.to include(*invariant_tasks) } + end end end