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 %>).
+
+
+
+
+ <%= @current_task_name.humanize %>
+
+
+
+
+
+
+
+
+
+ <% @tasks_presenter.provider_verification.each do |row| %>
+
+
+
+ <%= Array.wrap(row.claimant_answer).join("
").html_safe %>
+ |
+
+ <%= row.provider_answer %>
+ |
+
+ <% end %>
+
+
+ <% 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