diff --git a/app/models/base_policy.rb b/app/models/base_policy.rb index a9a327a0be..7ce56a6c5d 100644 --- a/app/models/base_policy.rb +++ b/app/models/base_policy.rb @@ -50,4 +50,8 @@ def searchable_eligibility_attributes def international_relocation_payments? to_s == "InternationalRelocationPayments" end + + def further_education_payments? + to_s == "FurtherEducationPayments" + end end diff --git a/app/models/claim_checking_tasks.rb b/app/models/claim_checking_tasks.rb index d46d0491ea..8a8e1f1261 100644 --- a/app/models/claim_checking_tasks.rb +++ b/app/models/claim_checking_tasks.rb @@ -31,6 +31,9 @@ def applicable_task_names task_names.delete("subject") task_names.delete("teaching_hours") end + unless claim.policy.further_education_payments? + task_names.delete("provider_verification") + end end end diff --git a/app/models/policies/further_education_payments/admin_provider_verification_task_presenter.rb b/app/models/policies/further_education_payments/admin_provider_verification_task_presenter.rb new file mode 100644 index 0000000000..c9e71b115f --- /dev/null +++ b/app/models/policies/further_education_payments/admin_provider_verification_task_presenter.rb @@ -0,0 +1,100 @@ +module Policies + module FurtherEducationPayments + class AdminProviderVerificationTaskPresenter + class Row < Struct.new( + :label, + :claimant_answer, + :provider_answer, + keyword_init: true + ); end + + ROWS = [ + ["contract_type", "contract_type", "contract_type"], + ["teaching_responsibilities", "teaching_responsibilities", "teaching_responsibilities"], + ["further_education_teaching_start_year", "further_education_teaching_start_year", "further_education_teaching_start_year"], + ["teaching_hours_per_week", "teaching_hours_per_week", "teaching_hours_per_week"], + ["half_teaching_hours", "half_teaching_hours", "half_teaching_hours"], + ["subjects_taught", "subjects_taught", "subjects_taught"], + ["courses_taught", "courses_taught", "subjects_taught"] + ] + + attr_reader :claim + + def initialize(claim) + @claim = claim + end + + def rows + ROWS.map do |label_key, claimant_key, provider_key| + Row.new( + label: label(label_key), + claimant_answer: claimant_answer(claimant_key), + provider_answer: provider_answer(provider_key) + ) + end + end + + private + + def label(key) + I18n.t( + [ + "further_education_payments", + "admin", + "task_questions", + "provider_verification", + key, + "label" + ].join(".") + ) + end + + def claimant_answer(key) + case key + when "subjects_taught" + subjects_taught + when "courses_taught" + courses_taught + when "further_education_teaching_start_year" + "September #{claim.eligibility.further_education_teaching_start_year} to August #{claim.eligibility.further_education_teaching_start_year.to_i + 1}" + else + I18n.t( + [ + "further_education_payments", + "admin", + "task_questions", + "provider_verification", + key, + "claimant_answers", + claim.eligibility.send(key) + ].join(".") + ) + end + end + + def provider_answer(key) + claim.eligibility.verification.fetch("assertions").find do |assertion| + assertion["name"] == key + end.fetch("outcome") ? "Yes" : "No" + end + + def subjects_taught + claim.eligibility.subjects_taught.map do |subject| + I18n.t( + [ + "further_education_payments", + "forms", + "subjects_taught", + "options", + subject + ].join(".") + ) + end + end + + def courses_taught + claim.eligibility.courses_taught.map(&:description) + end + 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 new file mode 100644 index 0000000000..950524c42c --- /dev/null +++ b/app/models/policies/further_education_payments/admin_tasks_presenter.rb @@ -0,0 +1,31 @@ +module Policies + module FurtherEducationPayments + class AdminTasksPresenter + include Admin::PresenterMethods + + attr_reader :claim + + def initialize(claim) + @claim = claim + end + + def provider_verification + AdminProviderVerificationTaskPresenter.new(claim).rows + end + + def provider_name + [verifier.fetch("first_name"), verifier.fetch("last_name")].join(" ") + end + + def provider_verification_submitted? + claim.eligibility.verification.present? + end + + private + + def verifier + @verifier ||= claim.eligibility.verification.fetch("verifier") + end + end + end +end diff --git a/app/models/policies/further_education_payments/eligibility_admin_answers_presenter.rb b/app/models/policies/further_education_payments/eligibility_admin_answers_presenter.rb new file mode 100644 index 0000000000..5494eb3b02 --- /dev/null +++ b/app/models/policies/further_education_payments/eligibility_admin_answers_presenter.rb @@ -0,0 +1,17 @@ +module Policies + module FurtherEducationPayments + class EligibilityAdminAnswersPresenter + include Admin::PresenterMethods + + attr_reader :eligibility + + def initialize(eligibility) + @eligibility = eligibility + end + + def answers + [] + end + end + end +end diff --git a/app/models/task.rb b/app/models/task.rb index ecfff3e220..fe3d9d7af5 100644 --- a/app/models/task.rb +++ b/app/models/task.rb @@ -9,6 +9,7 @@ class Task < ApplicationRecord NAMES = %w[ identity_confirmation + provider_verification visa arrival_date qualifications diff --git a/app/views/admin/tasks/provider_verification.html.erb b/app/views/admin/tasks/provider_verification.html.erb new file mode 100644 index 0000000000..9fe6a6faf9 --- /dev/null +++ b/app/views/admin/tasks/provider_verification.html.erb @@ -0,0 +1,75 @@ +<% content_for(:page_title) { page_title("Claim #{@claim.reference} provider verification check for# {@claim.policy.short_name}") } %> +<%= link_to "Back", admin_claim_tasks_path(claim_id: @claim.id), class: "govuk-back-link" %> +<%= render "shared/error_summary", instance: @task, errored_field_id_overrides: { "passed": "task_passed_true" } if @task.errors.any? %> + +
+ + <%= render "claim_summary", claim: @claim, heading: "Provider verification" %> + +
+

<%= @current_task_name.humanize %>

+ + <% if @tasks_presenter.provider_verification_submitted? %> +

+ This task was verified by the provider + (<%= @tasks_presenter.provider_name %>). +

+ + + + + + + + + + + + <% @tasks_presenter.provider_verification.each do |row| %> + + + + + + <% end %> + +
+ <%= @current_task_name.humanize %> +
+ Eligibility check + + Claimant submitted + + Provider response +
+ <%= row.label %> + + <%= Array.wrap(row.claimant_answer).join("

").html_safe %> +
+ <%= row.provider_answer %> +
+ <% else %> +

+ This task is pending verification by the provider +

+

+ Provider verification link <%= govuk_link_to( + Journeys::FurtherEducationPayments::Provider::SlugSequence.verify_claim_url(@claim), + Journeys::FurtherEducationPayments::Provider::SlugSequence.verify_claim_url(@claim) + ) %> +

+ <% end %> +
+ + <% if @tasks_presenter.provider_verification_submitted? %> +
+ <% if @task.persisted? %> + <%= render "task_outcome", task: @task, notes: @notes %> + <% else %> + <%= render "form", task_name: "provider_verification", claim: @claim %> + <% end %> + + <%= render partial: "admin/task_pagination" %> +
+ <% end %> +
diff --git a/config/locales/en.yml b/config/locales/en.yml index 9001a8786d..df73a689c7 100644 --- a/config/locales/en.yml +++ b/config/locales/en.yml @@ -138,6 +138,7 @@ en: employment: "Check employment information" matching_details: "Review matching details from other claims" identity_confirmation: "Confirm the claimant made the claim" + provider_verification: "Confirm the provider verification" payroll_gender: "Add a payroll gender for HMRC" student_loan_amount: "Check student loan amount" student_loan_plan: "Check student loan plan" @@ -149,6 +150,8 @@ en: employment_start: "Check employment start date" subject: "Check subject" teaching_hours: "Check teaching hours" + provider_verification: "Confirm the provider verification" + undo_decision: approved: "Undo approval" rejected: "Undo rejection" @@ -827,6 +830,38 @@ en: feedback_email: "FE-Levellingup.PremiumPayments@education.gov.uk" support_email_address: "FE-Levellingup.PremiumPayments@education.gov.uk" claim_subject: "Further education payment" + admin: + task_questions: + provider_verification: + title: "Has the provider confirmed the claimant's employment?" + contract_type: + label: "Contract of employment" + claimant_answers: + permanent: "Permanent" + fixed_term: "Fixed term" + variable_hours: "Variable hours" + teaching_responsibilities: + label: "Teaching responsibilities" + claimant_answers: + true: "Yes" + false: "No" + further_education_teaching_start_year: + label: "First 5 years of teaching" + teaching_hours_per_week: + label: "Timetabled teaching hours" + claimant_answers: + more_than_12: "More than 12 hours per week" + between_2_5_and_12: "Between 2.5 and 12 hours per week" + less_than_2_5: "Less than 2.5 hours per week" + half_teaching_hours: + label: "Age range taught" + claimant_answers: + true: "Yes" + false: "No" + subjects_taught: + label: "Subject" + courses_taught: + label: "Course" forms: ineligible: courses: diff --git a/spec/factories/policies/further_education_payments/eligibilities.rb b/spec/factories/policies/further_education_payments/eligibilities.rb index 478ca85c5c..7232301333 100644 --- a/spec/factories/policies/further_education_payments/eligibilities.rb +++ b/spec/factories/policies/further_education_payments/eligibilities.rb @@ -7,6 +7,15 @@ end trait :verified do + contract_type { "permanent" } + teaching_responsibilities { true } + further_education_teaching_start_year { "2023" } + teaching_hours_per_week { "more_than_12" } + hours_teaching_eligible_subjects { false } + half_teaching_hours { true } + subjects_taught { ["maths", "physics"] } + maths_courses { ["approved_level_321_maths", "gcse_maths"] } + physics_courses { ["gcse_physics"] } verification do { "assertions" => [ diff --git a/spec/features/admin/admin_claim_further_education_payments_spec.rb b/spec/features/admin/admin_claim_further_education_payments_spec.rb new file mode 100644 index 0000000000..b2fe6d84f7 --- /dev/null +++ b/spec/features/admin/admin_claim_further_education_payments_spec.rb @@ -0,0 +1,147 @@ +require "rails_helper" + +RSpec.feature "Admin claim further education payments" do + before do + create(:journey_configuration, :further_education_payments_provider) + sign_in_as_service_operator + end + + describe "Tasks" do + describe "provider verification task" do + context "when the provider is yet to verify the claim" do + it "shows the task as pending" do + fe_provider = create(:school, :further_education, name: "Springfield A and M") + + claim = create( + :claim, + first_name: "Edna", + surname: "Krabappel", + date_of_birth: Date.new(1945, 7, 3), + reference: "AB123456", + created_at: DateTime.new(2024, 8, 1, 9, 0, 0), + submitted_at: DateTime.new(2024, 8, 1, 9, 0, 0) + ) + + create( + :further_education_payments_eligibility, + contract_type: "fixed_term", + claim: claim, + school: fe_provider, + award_amount: 1500 + ) + + visit admin_claim_path(claim) + + click_on "View tasks" + + click_on "Confirm the provider verification" + + expect(page).to have_content( + "This task is pending verification by the provider" + ) + end + end + + context "when the provider has verified the claim" do + context "when the claim is for a fixed term contract" do + it "shows the verification information and allows the admin to complete the task" do + fe_provider = create(:school, :further_education, name: "Springfield A and M") + + claim = create( + :claim, + first_name: "Edna", + surname: "Krabappel", + date_of_birth: Date.new(1945, 7, 3), + reference: "AB123456", + created_at: DateTime.new(2024, 8, 1, 9, 0, 0), + submitted_at: DateTime.new(2024, 8, 1, 9, 0, 0) + ) + + create( + :further_education_payments_eligibility, + :verified, + contract_type: "fixed_term", + claim: claim, + school: fe_provider, + award_amount: 1500 + ) + + visit admin_claim_path(claim) + + click_on "View tasks" + + click_on "Confirm the provider verification" + + expect(page).to have_content( + "This task was verified by the provider (Seymoure Skinner)" + ) + + within_table_row("Contract of employment") do |claimant, provider| + expect(claimant).to have_text("Fixed term") + expect(provider).to have_text("Yes") + end + + within_table_row("Teaching responsibilities") do |claimant, provider| + expect(claimant).to have_text("Yes") + expect(provider).to have_text("Yes") + end + + within_table_row("First 5 years of teaching") do |claimant, provider| + expect(claimant).to have_text "September 2023 to August 2024" + expect(provider).to have_text "Yes" + end + + within_table_row("Timetabled teaching hours") do |claimant, provider| + expect(claimant).to have_text("More than 12 hours per week") + expect(provider).to have_text("Yes") + end + + within_table_row("Age range taught") do |claimant, provider| + expect(claimant).to have_text("Yes") + expect(provider).to have_text("No") + end + + within_table_row("Subject") do |claimant, provider| + expect(claimant).to have_text("Maths") + expect(claimant).to have_text("Physics") + expect(provider).to have_text("No") + end + + within_table_row("Course") do |claimant, provider| + expect(claimant).to have_content( + "Qualifications approved for funding at level 3 and below in " \ + "the mathematics and statistics (opens in new tab) sector subject area" \ + "GCSE in maths, functional skills qualifications and other " \ + "maths qualifications (opens in new tab) approved for teaching " \ + "to 16 to 19-year-olds who meet the condition of funding" \ + "GCSE physics" + ) + + expect(provider).to have_text("No") + end + + within_fieldset("Has the provider confirmed the claimant's employment?") do + choose "Yes" + end + + # FIXME RL: temp disabbling this as the task presenter hasn't been + # updated for the next page. + # click_on "Save and continue" + end + end + + context "when the claim is for a varible hours contract" do + end + end + end + end + + def within_table_row(label, &block) + within(find("tr", text: label)) do + claimant_answer = find("td:first-of-type") + provider_answer = find("td:last-of-type") + + yield(claimant_answer, provider_answer) + end + end +end