From d4cc77f57f4f25d3a1a73953e30c4b5c7b1bb654 Mon Sep 17 00:00:00 2001 From: Kat Date: Fri, 12 May 2023 10:54:38 +0100 Subject: [PATCH] Implement the soft validations only journey for sales logs --- ...bulk_upload_sales_data_check_controller.rb | 43 ++++++++++ .../bulk_upload_sales_data_check/confirm.rb | 30 +++++++ .../soft_errors_valid.rb | 40 +++++++++ app/services/bulk_upload/sales/validator.rb | 5 ++ .../confirm.html.erb | 22 +++++ .../soft_errors_valid.html.erb | 24 ++++++ config/locales/en.yml | 4 + config/routes.rb | 7 ++ ...upload_sales_data_check_controller_spec.rb | 82 +++++++++++++++++++ .../bulk_upload/sales/log_creator_spec.rb | 39 +++++++++ 10 files changed, 296 insertions(+) create mode 100644 app/controllers/bulk_upload_sales_data_check_controller.rb create mode 100644 app/models/forms/bulk_upload_sales_data_check/confirm.rb create mode 100644 app/models/forms/bulk_upload_sales_data_check/soft_errors_valid.rb create mode 100644 app/views/bulk_upload_sales_data_check/confirm.html.erb create mode 100644 app/views/bulk_upload_sales_data_check/soft_errors_valid.html.erb create mode 100644 spec/requests/bulk_upload_sales_data_check_controller_spec.rb diff --git a/app/controllers/bulk_upload_sales_data_check_controller.rb b/app/controllers/bulk_upload_sales_data_check_controller.rb new file mode 100644 index 000000000..3b79a98af --- /dev/null +++ b/app/controllers/bulk_upload_sales_data_check_controller.rb @@ -0,0 +1,43 @@ +class BulkUploadSalesDataCheckController < ApplicationController + include ActionView::Helpers::TextHelper + + before_action :authenticate_user! + + def show + @bulk_upload = current_user.bulk_uploads.find(params[:id]) + + render form.view_path + end + + def update + @bulk_upload = current_user.bulk_uploads.find(params[:id]) + + if form.valid? && form.save! + if params[:page] == "confirm" + n_logs = pluralize(@bulk_upload.logs.count, "log") + flash[:notice] = "You’ve successfully uploaded #{n_logs}" + end + + redirect_to form.next_path + else + render form.view_path + end + end + +private + + def form + @form ||= case params[:page] + when "soft-errors-valid" + Forms::BulkUploadSalesDataCheck::SoftErrorsValid.new(form_params.merge(bulk_upload: @bulk_upload)) + when "confirm" + Forms::BulkUploadSalesDataCheck::Confirm.new(form_params.merge(bulk_upload: @bulk_upload)) + else + raise "invalid form" + end + end + + def form_params + params.fetch(:form, {}).permit(:soft_errors_valid) + end +end diff --git a/app/models/forms/bulk_upload_sales_data_check/confirm.rb b/app/models/forms/bulk_upload_sales_data_check/confirm.rb new file mode 100644 index 000000000..033d4ee13 --- /dev/null +++ b/app/models/forms/bulk_upload_sales_data_check/confirm.rb @@ -0,0 +1,30 @@ +module Forms + module BulkUploadSalesDataCheck + class Confirm + include ActiveModel::Model + include ActiveModel::Attributes + include Rails.application.routes.url_helpers + + attribute :bulk_upload + + def view_path + "bulk_upload_sales_data_check/confirm" + end + + def back_path + page_bulk_upload_sales_data_check_path(bulk_upload, page: "soft-errors-valid") + end + + def next_path + sales_logs_path + end + + def save! + processor = BulkUpload::Processor.new(bulk_upload:) + processor.approve_and_confirm_soft_validations + + true + end + end + end +end diff --git a/app/models/forms/bulk_upload_sales_data_check/soft_errors_valid.rb b/app/models/forms/bulk_upload_sales_data_check/soft_errors_valid.rb new file mode 100644 index 000000000..5f8631f0d --- /dev/null +++ b/app/models/forms/bulk_upload_sales_data_check/soft_errors_valid.rb @@ -0,0 +1,40 @@ +module Forms + module BulkUploadSalesDataCheck + class SoftErrorsValid + include ActiveModel::Model + include ActiveModel::Attributes + include Rails.application.routes.url_helpers + + attribute :bulk_upload + attribute :soft_errors_valid, :string + + validates :soft_errors_valid, presence: true + + def options + [ + OpenStruct.new(id: "yes", name: "Yes, some of these are errors"), + OpenStruct.new(id: "no", name: "No, all the data is correct"), + ] + end + + def view_path + "bulk_upload_sales_data_check/soft_errors_valid" + end + + def next_path + case soft_errors_valid + when "yes" + page_bulk_upload_sales_resume_path(bulk_upload, page: "fix-choice") + when "no" + page_bulk_upload_sales_data_check_path(bulk_upload, page: "confirm") + else + raise "invalid choice" + end + end + + def save! + true + end + end + end +end diff --git a/app/services/bulk_upload/sales/validator.rb b/app/services/bulk_upload/sales/validator.rb index a72e3bbcf..2aa3bfd61 100644 --- a/app/services/bulk_upload/sales/validator.rb +++ b/app/services/bulk_upload/sales/validator.rb @@ -59,6 +59,11 @@ class BulkUpload::Sales::Validator row_parsers.any?(&:log_already_exists?) end + def soft_validation_errors_only? + errors = bulk_upload.bulk_upload_errors + errors.count == errors.where(category: "soft_validation").count && errors.count.positive? + end + private def any_logs_invalid? diff --git a/app/views/bulk_upload_sales_data_check/confirm.html.erb b/app/views/bulk_upload_sales_data_check/confirm.html.erb new file mode 100644 index 000000000..b2addaf28 --- /dev/null +++ b/app/views/bulk_upload_sales_data_check/confirm.html.erb @@ -0,0 +1,22 @@ +<% content_for :before_content do %> + <%= govuk_back_link href: @form.back_path %> +<% end %> + +
+
+ Bulk upload for sales (<%= @bulk_upload.year_combo %>) +

Are you sure you want to upload all logs from this bulk upload?

+ +

There are <%= pluralize(@bulk_upload.logs.count, "log") %> in this bulk upload, and <%= pluralize(@bulk_upload.bulk_upload_errors.count, "unexpected answer") %> will be marked as correct.

+ + <%= govuk_warning_text(icon_fallback_text: "Danger") do %> + You can not delete logs once you create them + <% end %> + + <%= form_with model: @form, scope: :form, url: page_bulk_upload_sales_data_check_path(@bulk_upload, page: "confirm"), method: :patch do |f| %> + <%= f.govuk_submit %> + + <%= govuk_button_link_to "Cancel", @form.back_path, secondary: true %> + <% end %> +
+
diff --git a/app/views/bulk_upload_sales_data_check/soft_errors_valid.html.erb b/app/views/bulk_upload_sales_data_check/soft_errors_valid.html.erb new file mode 100644 index 000000000..a8f246f7d --- /dev/null +++ b/app/views/bulk_upload_sales_data_check/soft_errors_valid.html.erb @@ -0,0 +1,24 @@ +
+
+ <%= form_with model: @form, scope: :form, url: page_bulk_upload_sales_data_check_path(@bulk_upload, page: "soft-errors-valid"), method: :patch do |f| %> + <%= f.govuk_error_summary %> + + Bulk upload for sales (<%= @bulk_upload.year_combo %>) +

Check these <%= pluralize(@bulk_upload.bulk_upload_errors.count, "answer") %>

+ +

Some data from your bulk upload might not be right. Check your file for any errors in the fields below.

+ +
+ <%= @bulk_upload.filename %> +
+ + <%= f.govuk_collection_radio_buttons :soft_errors_valid, + @form.options, + :id, + :name, + legend: { text: "Are there any errors in these fields?", size: "l" } %> + + <%= f.govuk_submit %> + <% end %> +
+
diff --git a/config/locales/en.yml b/config/locales/en.yml index b1044c774..f9e860709 100644 --- a/config/locales/en.yml +++ b/config/locales/en.yml @@ -77,6 +77,10 @@ en: attributes: soft_errors_valid: blank: You must select if there are errors in these fields + forms/bulk_upload_sales_data_check/soft_errors_valid: + attributes: + soft_errors_valid: + blank: You must select if there are errors in these fields activerecord: errors: diff --git a/config/routes.rb b/config/routes.rb index 813113d8b..a36ae5721 100644 --- a/config/routes.rb +++ b/config/routes.rb @@ -234,6 +234,13 @@ Rails.application.routes.draw do patch "*page", to: "bulk_upload_sales_resume#update" end end + + resources :bulk_upload_sales_data_check, path: "bulk-upload-data-check", only: %i[show update] do + member do + get "*page", to: "bulk_upload_sales_data_check#show", as: "page" + patch "*page", to: "bulk_upload_sales_data_check#update" + end + end end member do diff --git a/spec/requests/bulk_upload_sales_data_check_controller_spec.rb b/spec/requests/bulk_upload_sales_data_check_controller_spec.rb new file mode 100644 index 000000000..6a5a59ae7 --- /dev/null +++ b/spec/requests/bulk_upload_sales_data_check_controller_spec.rb @@ -0,0 +1,82 @@ +require "rails_helper" + +RSpec.describe BulkUploadSalesDataCheckController, type: :request do + let(:user) { create(:user) } + let(:bulk_upload) { create(:bulk_upload, :sales, user:, bulk_upload_errors:) } + let(:bulk_upload_errors) { create_list(:bulk_upload_error, 2) } + + before do + create_list(:sales_log, 2, bulk_upload:) + sign_in user + end + + describe "GET /sales-logs/bulk-upload-data-check/:ID/soft-errors-valid" do + it "shows the soft validation errors with confirmation question" do + get "/sales-logs/bulk-upload-data-check/#{bulk_upload.id}/soft-errors-valid" + + expect(response.body).to include("Bulk upload for sales") + expect(response.body).to include("2022/23") + expect(response.body).to include("Check these 2 answers") + expect(response.body).to include(bulk_upload.filename) + expect(response.body).to include("Are there any errors in these fields?") + end + end + + describe "PATCH /sales-logs/bulk-upload-data-check/:ID/soft-errors-valid" do + context "when no option selected" do + it "renders error message" do + patch "/sales-logs/bulk-upload-data-check/#{bulk_upload.id}/soft-errors-valid" + + expect(response).to be_successful + + expect(response.body).to include("You must select if there are errors in these fields") + end + end + + context "when yes is selected" do + it "sends them to the fix choice page" do + patch "/sales-logs/bulk-upload-data-check/#{bulk_upload.id}/soft-errors-valid", params: { form: { soft_errors_valid: "yes" } } + + expect(response).to redirect_to("/sales-logs/bulk-upload-resume/#{bulk_upload.id}/fix-choice") + end + end + + context "when no is selected" do + it "sends them to confirm choice" do + patch "/sales-logs/bulk-upload-data-check/#{bulk_upload.id}/soft-errors-valid", params: { form: { soft_errors_valid: "no" } } + + expect(response).to redirect_to("/sales-logs/bulk-upload-data-check/#{bulk_upload.id}/confirm") + follow_redirect! + expect(response.body).not_to include("You’ve successfully uploaded") + end + end + end + + describe "GET /sales-logs/bulk-upload-data-check/:ID/confirm" do + it "renders page" do + get "/sales-logs/bulk-upload-data-check/#{bulk_upload.id}/confirm" + + expect(response).to be_successful + + expect(response.body).to include("Are you sure you want to upload all logs from this bulk upload?") + expect(response.body).to include("There are 2 logs in this bulk upload, and 2 unexpected answers will be marked as correct.") + expect(response.body).not_to include("You’ve successfully uploaded") + end + end + + describe "PATCH /sales-logs/bulk-upload-data-check/:ID/confirm" do + let(:mock_processor) { instance_double(BulkUpload::Processor, approve_and_confirm_soft_validations: nil) } + + it "approves logs for creation" do + allow(BulkUpload::Processor).to receive(:new).with(bulk_upload:).and_return(mock_processor) + + patch "/sales-logs/bulk-upload-data-check/#{bulk_upload.id}/confirm" + + expect(mock_processor).to have_received(:approve_and_confirm_soft_validations) + + expect(response).to redirect_to("/sales-logs") + follow_redirect! + expect(response.body).to include("You’ve successfully uploaded 2 logs") + end + end +end diff --git a/spec/services/bulk_upload/sales/log_creator_spec.rb b/spec/services/bulk_upload/sales/log_creator_spec.rb index 2abda527d..14a363a4c 100644 --- a/spec/services/bulk_upload/sales/log_creator_spec.rb +++ b/spec/services/bulk_upload/sales/log_creator_spec.rb @@ -130,5 +130,44 @@ RSpec.describe BulkUpload::Sales::LogCreator do context "when valid csv with existing log" do xit "what should happen?" end + + context "with a valid csv and soft validations" do + let(:file) { Tempfile.new } + let(:path) { file.path } + let(:log) do + build( + :sales_log, + :completed, + age1: 30, + age1_known: 0, + ecstat1: 5, + owning_organisation: owning_org, + created_by: user, + ) + end + + before do + file.write(BulkUpload::SalesLogToCsv.new(log:, col_offset: 0).to_2022_csv_row) + file.rewind + end + + it "creates a new log" do + expect { service.call }.to change(SalesLog, :count) + end + + it "creates a log with pending status" do + service.call + expect(SalesLog.last.status).to eql("pending") + end + + it "does not set unanswered soft validations" do + service.call + + log = SalesLog.last + expect(log.age1).to be(30) + expect(log.ecstat1).to be(5) + expect(log.retirement_value_check).to be(nil) + end + end end end