diff --git a/app/controllers/claims/support/claims/clawbacks_controller.rb b/app/controllers/claims/support/claims/clawbacks_controller.rb
index 620baeb3e..b4618b99d 100644
--- a/app/controllers/claims/support/claims/clawbacks_controller.rb
+++ b/app/controllers/claims/support/claims/clawbacks_controller.rb
@@ -1,7 +1,10 @@
class Claims::Support::Claims::ClawbacksController < Claims::Support::ApplicationController
- before_action :skip_authorization
+ append_pundit_namespace :claims
+
before_action :set_filtered_claims, only: %i[index]
before_action :set_claim, only: %i[show]
+ before_action :authorize_claims
+
helper_method :filter_form
def index
@@ -12,6 +15,20 @@ def index
def show; end
+ def new
+ @clawback_requested_claims = Claims::Claim.clawback_requested
+
+ unless policy(Claims::Clawback).create?
+ render "new_not_permitted"
+ end
+ end
+
+ def create
+ Claims::Clawback::CreateAndDeliver.call(current_user:)
+
+ redirect_to claims_support_claims_clawbacks_path, flash: { success: true, heading: t(".success") }
+ end
+
private
def set_filtered_claims
@@ -49,4 +66,8 @@ def filter_params
def index_path
claims_support_claims_clawbacks_path
end
+
+ def authorize_claims
+ authorize [:clawbacks, set_filtered_claims]
+ end
end
diff --git a/app/policies/claims/support/claims/claim_policy.rb b/app/policies/claims/support/claims/claim_policy.rb
new file mode 100644
index 000000000..5ee604eb7
--- /dev/null
+++ b/app/policies/claims/support/claims/claim_policy.rb
@@ -0,0 +1,2 @@
+class Claims::Support::Claims::ClaimPolicy < Claims::Support::ClaimPolicy
+end
diff --git a/app/policies/claims/support/claims/clawback_policy.rb b/app/policies/claims/support/claims/clawback_policy.rb
new file mode 100644
index 000000000..2bba17de6
--- /dev/null
+++ b/app/policies/claims/support/claims/clawback_policy.rb
@@ -0,0 +1,9 @@
+class Claims::Support::Claims::ClawbackPolicy < Claims::ApplicationPolicy
+ def new?
+ true
+ end
+
+ def create?
+ Claims::Claim.clawback_requested.any?
+ end
+end
diff --git a/app/policies/claims/support/claims/clawbacks/claim_policy.rb b/app/policies/claims/support/claims/clawbacks/claim_policy.rb
new file mode 100644
index 000000000..e7bfddb23
--- /dev/null
+++ b/app/policies/claims/support/claims/clawbacks/claim_policy.rb
@@ -0,0 +1,2 @@
+class Claims::Support::Claims::Clawbacks::ClaimPolicy < Claims::ApplicationPolicy
+end
diff --git a/app/views/claims/support/claims/clawbacks/index.html.erb b/app/views/claims/support/claims/clawbacks/index.html.erb
index a681a4aba..bb5719d6a 100644
--- a/app/views/claims/support/claims/clawbacks/index.html.erb
+++ b/app/views/claims/support/claims/clawbacks/index.html.erb
@@ -9,6 +9,13 @@
<% if @claims.any? %>
+ <%= govuk_button_link_to t(".buttons.send_claims_to_esfa"), new_claims_support_claims_clawback_path %>
+ <%= govuk_button_link_to t(".buttons.upload_esfa_response"),
+ "",
+ secondary: true %>
+
+
<%= render Claims::Claim::FilterFormComponent.new(filter_form:, statuses: Claims::Claim::CLAWBACK_STATUSES) do %>
<% @claims.each do |claim| %>
diff --git a/app/views/claims/support/claims/clawbacks/new.html.erb b/app/views/claims/support/claims/clawbacks/new.html.erb
new file mode 100644
index 000000000..1091df584
--- /dev/null
+++ b/app/views/claims/support/claims/clawbacks/new.html.erb
@@ -0,0 +1,26 @@
+<%= render "claims/support/primary_navigation", current: :claims %>
+
+<% content_for(:page_title) { sanitize t(".page_title") } %>
+
+<% content_for(:before_content) do %>
+ <%= govuk_back_link href: claims_support_claims_clawbacks_path %>
+<% end %>
+
+
+
+
+
<%= t(".caption") %>
+
<%= t(".title") %>
+
+
<%= t(".description", count: @clawback_requested_claims.count) %>
+
+
<%= t(".details_html") %>
+
+ <%= govuk_warning_text text: t(".warning") %>
+
+ <%= govuk_button_to t(".submit"), claims_support_claims_clawbacks_path %>
+
+
<%= govuk_link_to t(".cancel"), claims_support_claims_clawbacks_path %>
+
+
+
diff --git a/app/views/claims/support/claims/clawbacks/new_not_permitted.html.erb b/app/views/claims/support/claims/clawbacks/new_not_permitted.html.erb
new file mode 100644
index 000000000..5b2d48f37
--- /dev/null
+++ b/app/views/claims/support/claims/clawbacks/new_not_permitted.html.erb
@@ -0,0 +1,19 @@
+<%= render "claims/support/primary_navigation", current: :claims %>
+<% content_for(:page_title) { sanitize t(".page_title") } %>
+
+<% content_for(:before_content) do %>
+ <%= govuk_back_link href: claims_support_claims_clawbacks_path %>
+<% end %>
+
+
+
+
+
<%= t(".caption") %>
+
<%= t(".title") %>
+
+
<%= t(".description") %>
+
+
<%= govuk_link_to t(".cancel"), claims_support_claims_clawbacks_path %>
+
+
+
diff --git a/config/locales/en/claims/support/claims/clawbacks.yml b/config/locales/en/claims/support/claims/clawbacks.yml
index 0f69d46ae..4699718c6 100644
--- a/config/locales/en/claims/support/claims/clawbacks.yml
+++ b/config/locales/en/claims/support/claims/clawbacks.yml
@@ -8,6 +8,9 @@ en:
sub_heading: Clawbacks (%{count})
sub_heading_without_count: Clawbacks
no_claims: There are no claims waiting to be processed.
+ buttons:
+ send_claims_to_esfa: Send claims to ESFA
+ upload_esfa_response: Upload ESFA response
show:
page_caption: Clawbacks - Claim %{reference}
page_title: "Clawbacks - %{school_name} - Claim %{reference}"
@@ -16,3 +19,29 @@ en:
mentor_with_index: Mentor %{index}
mentor: Mentor
submitted_by: Submitted by %{name} on %{date}.
+ new:
+ page_title: Send claims to ESFA - Clawbacks
+ caption: Clawbacks
+ title: Send claims to ESFA
+ description:
+ one: There is %{count} claim included in this submission.
+ other: There are %{count} claims included in this submission.
+ details_html:
+
Selecting ‘Send claims’ will:
+
+ - create a CSV containing a list of all claims marked as ‘Clawback requested’
+ - send an email to the ESFA containing a link to the generated CSV - this link expires after 7 days
+ - update the claim status from ‘Clawback requested’ to ‘Clawback in progress’
+
+ warning: This action cannot be undone.
+ submit: Send claims
+ cancel: Cancel
+ create:
+ success: Claims sent to ESFA
+ new_not_permitted:
+ page_title: There are no claims to send for clawback - Clawbacks
+ title: There are no claims to send for clawback
+ caption: Clawbacks
+ cancel: Cancel
+ description: You cannot send any claims to the ESFA because there are no claims with a clawback requested.
+
diff --git a/config/routes/claims.rb b/config/routes/claims.rb
index 62d4ceea3..45467b826 100644
--- a/config/routes/claims.rb
+++ b/config/routes/claims.rb
@@ -120,7 +120,7 @@
end
end
- resources :clawbacks, path: "clawbacks/claims", only: %i[index show] do
+ resources :clawbacks, path: "clawbacks/claims", only: %i[index show new create] do
get :remove, on: :member
collection do
diff --git a/spec/policies/claims/support/claims/clawback_policy_spec.rb b/spec/policies/claims/support/claims/clawback_policy_spec.rb
new file mode 100644
index 000000000..be2a74e73
--- /dev/null
+++ b/spec/policies/claims/support/claims/clawback_policy_spec.rb
@@ -0,0 +1,25 @@
+require "rails_helper"
+
+describe Claims::Support::Claims::ClawbackPolicy do
+ subject { described_class }
+
+ let(:support_user) { build(:claims_support_user) }
+
+ permissions :new? do
+ it { is_expected.to permit(support_user, Claims::Payment) }
+ end
+
+ permissions :create? do
+ context "when there are clawback requested claims" do
+ before do
+ create(:claim, :submitted, status: :clawback_requested)
+ end
+
+ it { is_expected.to permit(support_user, Claims::Payment) }
+ end
+
+ context "when there are no clawback requested claims" do
+ it { is_expected.not_to permit(support_user, Claims::Payment) }
+ end
+ end
+end
diff --git a/spec/system/claims/support/claims/clawbacks/send_to_esfa/support_user_can_not_send_claims_to_esfa_spec.rb b/spec/system/claims/support/claims/clawbacks/send_to_esfa/support_user_can_not_send_claims_to_esfa_spec.rb
new file mode 100644
index 000000000..7646b9bec
--- /dev/null
+++ b/spec/system/claims/support/claims/clawbacks/send_to_esfa/support_user_can_not_send_claims_to_esfa_spec.rb
@@ -0,0 +1,74 @@
+require "rails_helper"
+
+RSpec.describe "Support user can not send claims to ESFA", service: :claims, type: :system do
+ scenario do
+ given_claims_exist
+ and_i_am_signed_in
+
+ when_i_navigate_to_the_clawbacks_index_page
+ then_i_see_the_clawbacks_index_page
+ and_i_see_the_details_of_the_clawback_in_progress_claim
+
+ when_i_click_on_send_claims_to_esfa
+ then_i_see_the_are_no_claims_to_send_for_clawbacks
+ end
+
+ private
+
+ def given_claims_exist
+ @claim = create(:claim,
+ :submitted,
+ status: :clawback_in_progress)
+ end
+
+ def and_i_am_signed_in
+ sign_in_claims_support_user
+ end
+
+ def when_i_navigate_to_the_clawbacks_index_page
+ within primary_navigation do
+ click_on "Claims"
+ end
+
+ within secondary_navigation do
+ click_on "Clawbacks"
+ end
+ end
+
+ def then_i_see_the_clawbacks_index_page
+ expect(page).to have_title("Claims - Claim funding for mentor training - GOV.UK")
+ expect(page).to have_h1("Claims")
+ expect(page).to have_h2("Clawbacks (1)")
+ expect(primary_navigation).to have_current_item("Claims")
+ expect(secondary_navigation).to have_current_item("Clawbacks")
+ expect(page).to have_current_path(claims_support_claims_clawbacks_path, ignore_query: true)
+ end
+
+ def when_i_click_on_send_claims_to_esfa
+ click_on "Send claims to ESFA"
+ end
+
+ def and_i_see_the_details_of_the_clawback_in_progress_claim
+ expect(page).to have_claim_card({
+ "title" => "#{@claim.reference} - #{@claim.school.name}",
+ "url" => "/support/claims/clawbacks/claims/#{@claim.id}",
+ "status" => "Clawback in progress",
+ "academic_year" => @claim.academic_year.name,
+ "provider_name" => @claim.provider.name,
+ "submitted_at" => I18n.l(@claim.submitted_at.to_date, format: :long),
+ "amount" => "£0.00",
+ })
+ end
+
+ def then_i_see_the_are_no_claims_to_send_for_clawbacks
+ expect(page).to have_title(
+ "There are no claims to send for clawback - Clawbacks - Claim funding for mentor training - GOV.UK",
+ )
+ expect(page).to have_h1("There are no claims to send for clawback")
+ expect(page).to have_element(:p, text: "Clawbacks", class: "govuk-caption-l")
+ expect(page).to have_element(
+ :p,
+ text: "You cannot send any claims to the ESFA because there are no claims with a clawback requested.",
+ )
+ end
+end
diff --git a/spec/system/claims/support/claims/clawbacks/send_to_esfa/support_user_sends_claims_to_esfa_spec.rb b/spec/system/claims/support/claims/clawbacks/send_to_esfa/support_user_sends_claims_to_esfa_spec.rb
new file mode 100644
index 000000000..b13ae757b
--- /dev/null
+++ b/spec/system/claims/support/claims/clawbacks/send_to_esfa/support_user_sends_claims_to_esfa_spec.rb
@@ -0,0 +1,106 @@
+require "rails_helper"
+
+RSpec.describe "Support user sends claims to ESFA", service: :claims, type: :system do
+ scenario do
+ given_claims_exist
+ and_i_am_signed_in
+
+ when_i_navigate_to_the_clawbacks_index_page
+ then_i_see_the_clawbacks_index_page
+ and_i_see_the_details_of_the_clawback_requested_claim
+
+ when_i_click_on_send_claims_to_esfa
+ then_i_can_see_a_confirmation_page
+
+ when_i_click_on_send_claims
+ then_i_see_a_success_message
+ and_the_clawback_requested_claims_status_has_changed_to_clawback_in_progress
+ end
+
+ private
+
+ def given_claims_exist
+ @claim = create(:claim,
+ :submitted,
+ status: :clawback_requested)
+ end
+
+ def and_i_am_signed_in
+ sign_in_claims_support_user
+ end
+
+ def when_i_navigate_to_the_clawbacks_index_page
+ within primary_navigation do
+ click_on "Claims"
+ end
+
+ within secondary_navigation do
+ click_on "Clawbacks"
+ end
+ end
+
+ def then_i_see_the_clawbacks_index_page
+ expect(page).to have_title("Claims - Claim funding for mentor training - GOV.UK")
+ expect(page).to have_h1("Claims")
+ expect(page).to have_h2("Clawbacks (1)")
+ expect(primary_navigation).to have_current_item("Claims")
+ expect(secondary_navigation).to have_current_item("Clawbacks")
+ expect(page).to have_current_path(claims_support_claims_clawbacks_path, ignore_query: true)
+ end
+
+ def when_i_click_on_send_claims_to_esfa
+ click_on "Send claims to ESFA"
+ end
+
+ def then_i_can_see_a_confirmation_page
+ expect(page).to have_element(:p, text: "Clawbacks", class: "govuk-caption-l")
+ expect(page).to have_h1("Send claims to ESFA")
+ expect(page).to have_element(:p, text: "There is 1 claim included in this submission.", class: "govuk-body")
+ expect(page).to have_element(:div, text: "Selecting ‘Send claims’ will:", class: "govuk-body")
+ expect(page).to have_element(
+ :li,
+ text: "create a CSV containing a list of all claims marked as ‘Clawback requested’",
+ )
+ expect(page).to have_element(
+ :li,
+ text: "send an email to the ESFA containing a link to the generated CSV - this link expires after 7 days",
+ )
+ expect(page).to have_element(
+ :li,
+ text: "update the claim status from ‘Clawback requested’ to ‘Clawback in progress’",
+ )
+ expect(page).to have_warning_text("This action cannot be undone.")
+ end
+
+ def when_i_click_on_send_claims
+ click_on "Send claims"
+ end
+
+ def then_i_see_a_success_message
+ expect(page).to have_success_banner("Claims sent to ESFA")
+ end
+
+ def and_i_see_the_details_of_the_clawback_requested_claim
+ expect(page).to have_claim_card({
+ "title" => "#{@claim.reference} - #{@claim.school.name}",
+ "url" => "/support/claims/clawbacks/claims/#{@claim.id}",
+ "status" => "Clawback requested",
+ "academic_year" => @claim.academic_year.name,
+ "provider_name" => @claim.provider.name,
+ "submitted_at" => I18n.l(@claim.submitted_at.to_date, format: :long),
+ "amount" => "£0.00",
+ })
+ end
+
+ def and_the_clawback_requested_claims_status_has_changed_to_clawback_in_progress
+ expect(page).to have_claim_card({
+ "title" => "#{@claim.reference} - #{@claim.school.name}",
+ "url" => "/support/claims/clawbacks/claims/#{@claim.id}",
+ "status" => "Clawback in progress",
+ "academic_year" => @claim.academic_year.name,
+ "provider_name" => @claim.provider.name,
+ "submitted_at" => I18n.l(@claim.submitted_at.to_date, format: :long),
+ "amount" => "£0.00",
+ })
+ end
+end