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