diff --git a/app/controllers/fee_change_validation_requests_controller.rb b/app/controllers/fee_change_validation_requests_controller.rb new file mode 100644 index 00000000..0a41463c --- /dev/null +++ b/app/controllers/fee_change_validation_requests_controller.rb @@ -0,0 +1,46 @@ +# frozen_string_literal: true + +class FeeChangeValidationRequestsController < ValidationRequestsController + before_action :set_validation_request + + def show + respond_to do |format| + if validation_request_is_closed? || validation_request_is_cancelled? + format.html + else + format.html { render_not_found } + end + end + end + + def edit + respond_to do |format| + if validation_request_is_open? + @fee_change_validation_request = build_validation_request + format.html + else + format.html { render_not_found } + end + end + end + + def update + @fee_change_validation_request = build_validation_request(fee_change_validation_request_params) + + respond_to do |format| + if @fee_change_validation_request.update + flash[:notice] = t("shared.response_updated.success") + format.html { validation_requests_redirect_url } + else + flash[:error] = error_message(@fee_change_validation_request) + format.html { render :edit } + end + end + end + + private + + def fee_change_validation_request_params + params.require(:fee_change_validation_request).permit(:response) + end +end diff --git a/app/helpers/validation_requests_helper.rb b/app/helpers/validation_requests_helper.rb index 86656201..1ed2e4f7 100644 --- a/app/helpers/validation_requests_helper.rb +++ b/app/helpers/validation_requests_helper.rb @@ -26,6 +26,7 @@ def flattened_validation_requests(validation_requests) validation_requests["data"]["description_change_validation_requests"] + validation_requests["data"]["replacement_document_validation_requests"] + validation_requests["data"]["other_change_validation_requests"] + + validation_requests["data"]["fee_change_validation_requests"] + validation_requests["data"]["red_line_boundary_change_validation_requests"] end @@ -42,6 +43,7 @@ def ordered_validation_requests replacement_document_validation_requests additional_document_validation_requests red_line_boundary_change_validation_requests + fee_change_validation_requests other_change_validation_requests] end diff --git a/app/models/bops/fee_change_validation_request.rb b/app/models/bops/fee_change_validation_request.rb new file mode 100644 index 00000000..67adc723 --- /dev/null +++ b/app/models/bops/fee_change_validation_request.rb @@ -0,0 +1,27 @@ +# frozen_string_literal: true + +module Bops + class FeeChangeValidationRequest + include ActiveModel::Model + + attr_accessor :response, :planning_application_id, :change_access_id, :id + + validates :response, presence: true + + class << self + def find(id, planning_application_id, change_access_id) + Apis::Bops::Client.get_fee_change_validation_request(id, planning_application_id, change_access_id) + end + + def respond(id, planning_application_id, change_access_id, response) + Apis::Bops::Client.patch_response_fee_change_request(id, planning_application_id, change_access_id, response) + end + end + + def update + return false unless valid? + + self.class.respond(id, planning_application_id, change_access_id, response) + end + end +end diff --git a/app/services/apis/bops/client.rb b/app/services/apis/bops/client.rb index fe60b7ac..5d44a6b6 100644 --- a/app/services/apis/bops/client.rb +++ b/app/services/apis/bops/client.rb @@ -78,6 +78,26 @@ def patch_rejected_description_change(id, planning_application_id, change_access ) end + # Fee change validation requests + def get_fee_change_validation_request(id, planning_application_id, change_access_id) + request( + http_method: :get, + endpoint: "planning_applications/#{planning_application_id}/fee_change_validation_requests/#{id}?change_access_id=#{change_access_id}" + ) + end + + def patch_response_fee_change_request(id, planning_application_id, change_access_id, response) + request( + http_method: :patch, + endpoint: "planning_applications/#{planning_application_id}/fee_change_validation_requests/#{id}?change_access_id=#{change_access_id}", + params: { + data: { + response: + } + }.to_json + ) + end + # Other change validation requests def get_other_change_validation_request(id, planning_application_id, change_access_id) request( diff --git a/app/views/fee_change_validation_requests/_form.html.erb b/app/views/fee_change_validation_requests/_form.html.erb new file mode 100644 index 00000000..2dfbab0e --- /dev/null +++ b/app/views/fee_change_validation_requests/_form.html.erb @@ -0,0 +1,30 @@ +<%= form_with scope: :fee_change_validation_request, + url: fee_change_validation_request_path(@validation_request["id"], planning_application_id: params["planning_application_id"], change_access_id: params["change_access_id"]), + method: :patch, + builder: GOVUKDesignSystemFormBuilder::FormBuilder do |form| %> + + <% if @fee_change_validation_request.errors.any? %> + + <% end %> + +
"> +
+ <%= form.govuk_text_area :response, label: { text: "Respond to this request" }, rows: 6 %> +
+
+
+ <%= form.submit "Submit", class: "govuk-button", data: { module: "govuk-button" } %> + <%= link_to 'Back', validation_requests_path(planning_application_id: params["planning_application_id"], change_access_id: params["change_access_id"]), class: "govuk-button govuk-button--secondary" %> +
+<% end %> diff --git a/app/views/fee_change_validation_requests/edit.html.erb b/app/views/fee_change_validation_requests/edit.html.erb new file mode 100644 index 00000000..0167f78b --- /dev/null +++ b/app/views/fee_change_validation_requests/edit.html.erb @@ -0,0 +1,35 @@ +<% content_for :page_title do %> + <%= t(".page_title", id: @validation_request["id"]) %> +<% end %> +
+
+
+

<%= t(".title") %>

+

<%= t(".the_following_request") %>

+

<%= t(".what_you_need") %>

+
    +
  • <%= t(".make_changes_to") %>
  • +
  • <%= t(".if_you_disagree") %>
  • +
  • <%= t(".click_submit_to") %>
  • +
+
+ <%= t(".if_your_response", date: date_due(@validation_request)) %> +
+
+
+

+ <%= t(".officers_reason_for") %>
+ <%= render(FormattedContentComponent.new(text: @validation_request["reason"])) %> +

+
+
+

+ <%= t(".how_you_can") %>
+ <%= render(FormattedContentComponent.new(text: @validation_request["suggestion"])) %> +

+
+
+ <%= render 'form' %> +
+
+
diff --git a/app/views/fee_change_validation_requests/show.html.erb b/app/views/fee_change_validation_requests/show.html.erb new file mode 100644 index 00000000..c962301f --- /dev/null +++ b/app/views/fee_change_validation_requests/show.html.erb @@ -0,0 +1,42 @@ +<% content_for :page_title do %> + Other change validation request #<%= @validation_request["id"] %> - Back-Office Planning System +<% end %> + +
+
+
+ <% if @validation_request["state"] == "cancelled" %> + <%= render "validation_requests/cancelled", + validation_request: @validation_request, + heading: "Cancelled fee change request on your application" %> + <% else %> +

Response to fee change request

+
+

+ Officer's reason for invalidating application
+

+

+ <%= render(FormattedContentComponent.new(text: @validation_request["reason"])) %> +

+

+ How you can make your application valid
+

+

+ <%= @validation_request["suggestion"] %> +

+
+

+ My response to this request
+

+

+ <%= render(FormattedContentComponent.new(text: @validation_request["response"])) %> +

+
+ <% end %> + +
+ <%= link_to 'Back', validation_requests_path(planning_application_id: params["planning_application_id"], change_access_id: params["change_access_id"]), class: "govuk-button govuk-button--secondary" %> +
+
+
+
diff --git a/app/views/other_change_validation_requests/edit.html.erb b/app/views/other_change_validation_requests/edit.html.erb index a63de885..b33c8c96 100644 --- a/app/views/other_change_validation_requests/edit.html.erb +++ b/app/views/other_change_validation_requests/edit.html.erb @@ -19,7 +19,7 @@

<%= t(".officers_reason_for") %>
- <%= render(FormattedContentComponent.new(text: @validation_request["summary"])) %> + <%= render(FormattedContentComponent.new(text: @validation_request["reason"])) %>

diff --git a/app/views/other_change_validation_requests/show.html.erb b/app/views/other_change_validation_requests/show.html.erb index 535a1213..172fee1b 100644 --- a/app/views/other_change_validation_requests/show.html.erb +++ b/app/views/other_change_validation_requests/show.html.erb @@ -16,7 +16,7 @@ Officer's reason for invalidating application

- <%= render(FormattedContentComponent.new(text: @validation_request["summary"])) %> + <%= render(FormattedContentComponent.new(text: @validation_request["reason"])) %>

How you can make your application valid
diff --git a/app/views/validation_requests/_cancelled.html.erb b/app/views/validation_requests/_cancelled.html.erb index 040b0232..31301344 100644 --- a/app/views/validation_requests/_cancelled.html.erb +++ b/app/views/validation_requests/_cancelled.html.erb @@ -4,9 +4,7 @@ The officer gave the following reason for cancelling this request:

-

- <%= render(FormattedContentComponent.new(text: validation_request["cancel_reason"])) %> -

+ <%= render(FormattedContentComponent.new(text: validation_request["cancel_reason"])) %>

<%= validation_request["cancelled_at"].to_time.to_formatted_s(:day_month_year) %>

diff --git a/app/views/validation_requests/_fee_change_validation_requests.html.erb b/app/views/validation_requests/_fee_change_validation_requests.html.erb new file mode 100644 index 00000000..5b309840 --- /dev/null +++ b/app/views/validation_requests/_fee_change_validation_requests.html.erb @@ -0,0 +1,19 @@ +
  • +

    + <%= count_total_requests(@validation_requests, "fee_change_validation_requests") %> + Respond to fee change request +

    +
      + <% @validation_requests["data"]["fee_change_validation_requests"].each do |change_request| %> +
    • + <% if change_request["state"] == "open" %> + <%= link_to "Fee change", edit_fee_change_validation_request_path(change_request["id"], planning_application_id: params["planning_application_id"], change_access_id: params["change_access_id"]), class: "moj-task-list__task-name" %> + <% else %> + <%= link_to "Fee change", fee_change_validation_request_path(change_request["id"], planning_application_id: params["planning_application_id"], change_access_id: params["change_access_id"]), class: "moj-task-list__task-name" %> + <% end %> + + <%= render "validation_requests/change_request_state", change_request: change_request %> +
    • + <% end %> +
    +
  • diff --git a/app/views/validation_requests/index.html.erb b/app/views/validation_requests/index.html.erb index c764776d..9da23cd1 100644 --- a/app/views/validation_requests/index.html.erb +++ b/app/views/validation_requests/index.html.erb @@ -40,6 +40,10 @@ <%= render "red_line_boundary_change_validation_requests" %> <% end %> + <% if @validation_requests["data"]["fee_change_validation_requests"].present? %> + <%= render "fee_change_validation_requests" %> + <% end %> + <% if @validation_requests["data"]["other_change_validation_requests"].present? %> <%= render "other_change_validation_requests" %> <% end %> diff --git a/config/locales/en.yml b/config/locales/en.yml index a414d984..10ea467a 100644 --- a/config/locales/en.yml +++ b/config/locales/en.yml @@ -23,6 +23,18 @@ en: the_following_changes: The following changes have been made to your application's description. title: Confirm changes to your application description what_you_need: "What you need to do:" + fee_change_validation_requests: + edit: + click_submit_to: Click submit to complete this action + how_you_can: How you can make your application valid + if_you_disagree: If you disagree with the suggested changes, reply stating why you disagree + if_your_response: If your response is not received by %{date} your application will be returned to you and your payment refunded. + make_changes_to: Make changes to your application as set out by your case officer and reply in the box below stating what changes have been made + officers_reason_for: Officer's reason for invalidating application + page_title: "Fee change validation request #%{id} - Back-Office Planning System" + the_following_request: The following request has been made. + title: Respond to fee change request + what_you_need: "What you need to do:" other_change_validation_requests: edit: click_submit_to: Click submit to complete this action @@ -166,6 +178,10 @@ en: attributes: files: blank: "Please choose at least one file to upload" + bops/fee_change_validation_request: + attributes: + response: + blank: "Please enter your response to the planning officer's question." bops/replacement_document_validation_request: attributes: file: diff --git a/config/routes.rb b/config/routes.rb index 57422fe6..c00c054b 100644 --- a/config/routes.rb +++ b/config/routes.rb @@ -8,6 +8,7 @@ resources :replacement_document_validation_requests resources :additional_document_validation_requests resources :other_change_validation_requests + resources :fee_change_validation_requests resources :red_line_boundary_change_validation_requests end diff --git a/spec/helpers/validation_requests_helper_spec.rb b/spec/helpers/validation_requests_helper_spec.rb index 5bf51dda..6fc68400 100644 --- a/spec/helpers/validation_requests_helper_spec.rb +++ b/spec/helpers/validation_requests_helper_spec.rb @@ -26,6 +26,10 @@ "other_change_validation_requests" => [ {"response_due" => "2021-06-01"}, {"response_due" => "2021-06-02"} + ], + "fee_change_validation_requests" => [ + {"response_due" => "2021-06-01"}, + {"response_due" => "2021-06-02"} ] } })).to eq({"response_due" => "2021-06-12"}) @@ -53,6 +57,10 @@ "other_change_validation_requests" => [ {"response_due" => "2021-05-29"}, {"response_due" => "2021-05-30"} + ], + "fee_change_validation_requests" => [ + {"response_due" => "2021-06-01"}, + {"response_due" => "2021-06-02"} ] } })).to eq({"response_due" => "2021-06-11"}) @@ -80,6 +88,10 @@ "other_change_validation_requests" => [ {"response_due" => "2021-06-29"}, {"response_due" => "2021-06-30"} + ], + "fee_change_validation_requests" => [ + {"response_due" => "2021-06-01"}, + {"response_due" => "2021-06-02"} ] } })).to eq({"response_due" => "2021-07-12"}) @@ -107,6 +119,10 @@ "other_change_validation_requests" => [ {"response_due" => "2021-06-29"}, {"response_due" => "2021-06-30"} + ], + "fee_change_validation_requests" => [ + {"response_due" => "2021-06-01"}, + {"response_due" => "2021-06-02"} ] } })).to eq({"response_due" => "2021-06-30"}) @@ -134,6 +150,10 @@ "other_change_validation_requests" => [ {"response_due" => "2021-06-29"}, {"response_due" => "2021-06-30"} + ], + "fee_change_validation_requests" => [ + {"response_due" => "2021-06-01"}, + {"response_due" => "2021-06-02"} ] } })).to eq({"response_due" => "2021-07-02"}) diff --git a/spec/support/bops_api_request_stubs/fee_change_validation_request.rb b/spec/support/bops_api_request_stubs/fee_change_validation_request.rb new file mode 100644 index 00000000..bb02eb36 --- /dev/null +++ b/spec/support/bops_api_request_stubs/fee_change_validation_request.rb @@ -0,0 +1,36 @@ +# frozen_string_literal: true + +RSpec.configure do |config| + helpers = Module.new do + def stub_get_fee_change_validation_request(id:, planning_id:, change_access_id:, response_body:, status:) + stub_request( + :get, + "#{ApiSpecHelper::API_BASE_URL}/#{planning_id}/fee_change_validation_requests/#{id}?change_access_id=#{change_access_id}" + ) + .with( + headers: + ) + .to_return( + body: JSON.generate(response_body), + status: + ) + end + + def stub_patch_fee_change_validation_request(id:, planning_id:, change_access_id:, response:, status:) + stub_request( + :patch, + "#{ApiSpecHelper::API_BASE_URL}/#{planning_id}/fee_change_validation_requests/#{id}?change_access_id=#{change_access_id}" + ) + .with( + headers:, + body: {data: {response:}}.to_json + ) + .to_return( + body: "{}", + status: + ) + end + end + + config.include helpers, type: :system +end diff --git a/spec/system/fee_change_validation_request_spec.rb b/spec/system/fee_change_validation_request_spec.rb new file mode 100644 index 00000000..f5b3f559 --- /dev/null +++ b/spec/system/fee_change_validation_request_spec.rb @@ -0,0 +1,168 @@ +# frozen_string_literal: true + +require "rails_helper" + +RSpec.describe "Other change requests", type: :system do + include_context "local_authority_contact_details" + + before do + Rails.configuration.api_bearer = "123" + Rails.configuration.api_protocol = "https" + + stub_successful_get_planning_application + stub_get_fee_change_validation_request( + id: 19, + planning_id: 28, + change_access_id: 345_443_543, + response_body: + { + id: 19, + state: "open", + reason: "You paid the wrong amount", + suggestion: "Please pay more money", + response_due: "2022-7-1" + }, + status: 200 + ) + end + + context "when state is open" do + before do + stub_patch_fee_change_validation_request( + id: 19, + planning_id: 28, + change_access_id: 345_443_543, + response: "Agreed", + status: 200 + ) + end + + it "allows the user to provide a response" do + visit "/fee_change_validation_requests/19/edit?change_access_id=345443543&planning_application_id=28" + + expect(page).to have_content( + "If your response is not received by 1 July 2022 your application will be returned to you and your payment refunded." + ) + + expect(page).to have_content("You paid the wrong amount") + expect(page).to have_content("Please pay more money") + + fill_in "Respond to this request", with: "Agreed" + + stub_successful_get_change_requests + click_button "Submit" + + expect(page).to have_content("Your response was updated successfully") + end + + it "can't view show action" do + visit "/fee_change_validation_requests/19?change_access_id=345443543&planning_application_id=28" + expect(page).to have_content("Not Found") + end + + it "does not allow the user to submit a blank response" do + visit "/fee_change_validation_requests/19/edit?change_access_id=345443543&planning_application_id=28" + + click_button "Submit" + within(".govuk-error-summary") do + expect(page).to have_content "Please enter your response to the planning officer's question." + end + end + + it "has the correct page title" do + visit "/fee_change_validation_requests/19/edit?change_access_id=345443543&planning_application_id=28" + + expect(page).to have_title("Fee change validation request #19 - Back-Office Planning System") + end + end + + context "when state is closed" do + before do + stub_get_fee_change_validation_request( + id: 19, + planning_id: 28, + change_access_id: 345_443_543, + response_body: + { + id: 19, + state: "closed", + response: "I accept the change" + }, + status: 200 + ) + end + + it "can't view edit action" do + visit "/fee_change_validation_requests/19/edit?change_access_id=345443543&planning_application_id=28" + expect(page).to have_content("Not Found") + end + + it "view the page for a closed fee change validation request" do + visit "/fee_change_validation_requests/19?change_access_id=345443543&planning_application_id=28" + expect(page).to have_content("My response to this request") + expect(page).to have_content("I accept the change") + end + end + + context "when state is cancelled" do + before do + stub_get_fee_change_validation_request( + id: 19, + planning_id: 28, + change_access_id: 345_443_543, + response_body: + { + id: 19, + state: "cancelled", + cancel_reason: "My mistake", + cancelled_at: "2021-10-20T11:42:50.951+01:00" + }, + status: 200 + ) + end + + it "displays a cancellation summary for a cancelled validation request" do + visit "/fee_change_validation_requests/19?change_access_id=345443543&planning_application_id=28" + + expect(page).to have_content "Cancelled fee change request on your application" + expect(page).to have_content "This request has been cancelled. You do not have to take any further actions." + expect(page).to have_content "The officer gave the following reason for cancelling this request:" + expect(page).to have_content "My mistake" + expect(page).to have_content "20 October 2021" + expect(page).to have_link "Back", href: "/validation_requests?change_access_id=345443543&planning_application_id=28" + end + end + + context "when an officer adds a link in the suggestion/summary fields" do + before do + stub_get_fee_change_validation_request( + id: 19, + planning_id: 28, + change_access_id: 345_443_543, + response_body: + { + id: 19, + state: "open", + reason: "Details are on https://www.bops.co.uk/info", + suggestion: "View to see Payment info", + response_due: "2022-7-1" + }, + status: 200 + ) + end + + it "displays the link and link html as clickable" do + visit "/fee_change_validation_requests/19/edit?change_access_id=345443543&planning_application_id=28" + + expect(page).to have_link( + "https://www.bops.co.uk/info", + href: "https://www.bops.co.uk/info" + ) + + expect(page).to have_link( + "Payment info", + href: "https://www.bops.co.uk/payment" + ) + end + end +end diff --git a/spec/system/other_change_validation_request_spec.rb b/spec/system/other_change_validation_request_spec.rb index bedc6d4f..968b1b11 100644 --- a/spec/system/other_change_validation_request_spec.rb +++ b/spec/system/other_change_validation_request_spec.rb @@ -18,7 +18,7 @@ { id: 19, state: "open", - summary: "You applied for the wrong sort of certificate", + reason: "You applied for the wrong sort of certificate", suggestion: "Please confirm you want a Lawful Development certificate", response_due: "2022-7-1" }, @@ -133,7 +133,7 @@ end end - context "when an officer adds a link in the suggestion/summary fields" do + context "when an officer adds a link in the suggestion/reason fields" do before do stub_get_other_change_validation_request( id: 19, @@ -143,7 +143,7 @@ { id: 19, state: "open", - summary: "Details are on https://www.bops.co.uk/info", + reason: "Details are on https://www.bops.co.uk/info", suggestion: "View to see Payment info", response_due: "2022-7-1" },