From 9d843c01443d6d7778a5b332bd5b1b2d20bde755 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 | 30 ++++++ config/locales/en.yml | 6 ++ ...s_further_education_payments_claim_spec.rb | 97 +++++++++++++++++++ ...n_claim_further_education_payments_spec.rb | 6 ++ .../claim_checking_tasks_spec.rb | 35 ++++++- 10 files changed, 219 insertions(+), 2 deletions(-) create mode 100644 app/views/admin/tasks/provider_details.html.erb diff --git a/app/models/claim_checking_tasks.rb b/app/models/claim_checking_tasks.rb index c7c74fae94..dfe336a78d 100644 --- a/app/models/claim_checking_tasks.rb +++ b/app/models/claim_checking_tasks.rb @@ -51,6 +51,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 85d322c3db..d3e7153181 100644 --- a/app/models/policies/further_education_payments/admin_tasks_presenter.rb +++ b/app/models/policies/further_education_payments/admin_tasks_presenter.rb @@ -42,6 +42,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 67471388b5..ab08d42722 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 01ace6850c..231f27375b 100644 --- a/app/models/policies/further_education_payments/eligibility.rb +++ b/app/models/policies/further_education_payments/eligibility.rb @@ -77,6 +77,41 @@ def awaiting_provider_verification? # when a provider verification email is sent by the admin team, a note is created !flagged_as_duplicate? || claim.notes.where(label: "provider_verification").any? 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 e0aa4c8679..77023f8492 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..bdf5d255da --- /dev/null +++ b/app/views/admin/tasks/provider_details.html.erb @@ -0,0 +1,30 @@ +<% 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", + locals: { task_pagination: @task_pagination } + ) %> +
+
diff --git a/config/locales/en.yml b/config/locales/en.yml index 3d42549d03..267204fcbc 100644 --- a/config/locales/en.yml +++ b/config/locales/en.yml @@ -143,6 +143,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?’" @@ -950,6 +952,10 @@ en: false: "No" employment: title: Does the claimant’s place of work match the above information on their claim? + 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: ineligible: courses: 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 index 5a5f01983a..d5ce703891 100644 --- a/spec/features/admin/admin_checks_further_education_payments_claim_spec.rb +++ b/spec/features/admin/admin_checks_further_education_payments_claim_spec.rb @@ -2,4 +2,101 @@ RSpec.feature "Admin checks an Further Education Payments claim" do it_behaves_like "Admin Checks", Policies::FurtherEducationPayments + + describe "further education specific checks" 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 end diff --git a/spec/features/admin/admin_claim_further_education_payments_spec.rb b/spec/features/admin/admin_claim_further_education_payments_spec.rb index 0d758c20f4..df46ad96c5 100644 --- a/spec/features/admin/admin_claim_further_education_payments_spec.rb +++ b/spec/features/admin/admin_claim_further_education_payments_spec.rb @@ -28,6 +28,7 @@ :claim, first_name: "Edna", surname: "Krabappel", + email_address: "edna.krabappel@springfield-elementary.edu", date_of_birth: Date.new(1945, 7, 3), reference: "AB123456", created_at: DateTime.new(2024, 8, 1, 9, 0, 0), @@ -99,6 +100,7 @@ :claim, first_name: "Edna", surname: "Krabappel", + email_address: "edna.krabappel@springfield-elementary.edu", date_of_birth: Date.new(1945, 7, 3), reference: "AB123456", created_at: DateTime.new(2024, 8, 1, 9, 0, 0), @@ -178,6 +180,7 @@ :claim, first_name: "Edna", surname: "Krabappel", + email_address: "edna.krabappel@springfield-elementary.edu", date_of_birth: Date.new(1945, 7, 3), reference: "AB123456", created_at: DateTime.new(2024, 8, 1, 9, 0, 0), @@ -249,6 +252,7 @@ :claim, first_name: "Edna", surname: "Krabappel", + email_address: "edna.krabappel@springfield-elementary.edu", date_of_birth: Date.new(1945, 7, 3), reference: "AB123456", created_at: DateTime.new(2024, 8, 1, 9, 0, 0), @@ -295,6 +299,7 @@ :claim, first_name: "Edna", surname: "Krabappel", + email_address: "edna.krabappel@springfield-elementary.edu", date_of_birth: Date.new(1945, 7, 3), reference: "AB123456", created_at: DateTime.new(2024, 8, 1, 9, 0, 0), @@ -387,6 +392,7 @@ :claim, first_name: "Edna", surname: "Krabappel", + email_address: "edna.krabappel@springfield-elementary.edu", date_of_birth: Date.new(1945, 7, 3), reference: "AB123456", created_at: DateTime.new(2024, 8, 1, 9, 0, 0), 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