diff --git a/app/controllers/bulk_upload_lettings_results_controller.rb b/app/controllers/bulk_upload_lettings_results_controller.rb
index a0a962b3e..1c5342cd8 100644
--- a/app/controllers/bulk_upload_lettings_results_controller.rb
+++ b/app/controllers/bulk_upload_lettings_results_controller.rb
@@ -6,4 +6,32 @@ class BulkUploadLettingsResultsController < ApplicationController
def show
@bulk_upload = current_user.bulk_uploads.lettings.find(params[:id])
end
+
+ def resume
+ @bulk_upload = current_user.bulk_uploads.lettings.find(params[:id])
+
+ if @bulk_upload.lettings_logs.in_progress.count.positive?
+ set_bulk_upload_logs_filters
+
+ redirect_to(lettings_logs_path(bulk_upload_id: [@bulk_upload.id]))
+ else
+ reset_logs_filters
+ end
+ end
+
+private
+
+ def reset_logs_filters
+ session["logs_filters"] = {}.to_json
+ end
+
+ def set_bulk_upload_logs_filters
+ hash = {
+ years: [""],
+ status: ["", "in_progress"],
+ user: "all",
+ }
+
+ session["logs_filters"] = hash.to_json
+ end
end
diff --git a/app/controllers/lettings_logs_controller.rb b/app/controllers/lettings_logs_controller.rb
index e7d233f87..a7bc2dc56 100644
--- a/app/controllers/lettings_logs_controller.rb
+++ b/app/controllers/lettings_logs_controller.rb
@@ -3,6 +3,9 @@ class LettingsLogsController < LogsController
before_action :session_filters, if: :current_user
before_action :set_session_filters, if: :current_user
+ before_action :extract_bulk_upload_from_session_filters, only: [:index]
+ before_action :redirect_if_bulk_upload_resolved, only: [:index]
+
def index
respond_to do |format|
format.html do
@@ -109,6 +112,17 @@ class LettingsLogsController < LogsController
private
+ def redirect_if_bulk_upload_resolved
+ if @bulk_upload && @bulk_upload.lettings_logs.in_progress.count.zero?
+ redirect_to resume_bulk_upload_lettings_result_path(@bulk_upload)
+ end
+ end
+
+ def extract_bulk_upload_from_session_filters
+ id = ((@session_filters["bulk_upload_id"] || []).reject(&:blank?))[0]
+ @bulk_upload = current_user.bulk_uploads.find_by(id:)
+ end
+
def permitted_log_params
params.require(:lettings_log).permit(LettingsLog.editable_fields)
end
diff --git a/app/controllers/modules/logs_filter.rb b/app/controllers/modules/logs_filter.rb
index 7c60bb027..06109cfb0 100644
--- a/app/controllers/modules/logs_filter.rb
+++ b/app/controllers/modules/logs_filter.rb
@@ -7,7 +7,9 @@ module Modules::LogsFilter
def load_session_filters(specific_org: false)
current_filters = session[:logs_filters]
new_filters = current_filters.present? ? JSON.parse(current_filters) : {}
- current_user.logs_filters(specific_org:).each { |filter| new_filters[filter] = params[filter] if params[filter].present? }
+ current_user.logs_filters(specific_org:).each do |filter|
+ new_filters[filter] = params[filter] if params[filter].present?
+ end
params["organisation_select"] == "all" ? new_filters.except("organisation") : new_filters
end
diff --git a/app/helpers/logs_helper.rb b/app/helpers/logs_helper.rb
index 6567f0a13..88ab2b314 100644
--- a/app/helpers/logs_helper.rb
+++ b/app/helpers/logs_helper.rb
@@ -18,4 +18,9 @@ module LogsHelper
bulk_upload_sales_log_path(id:)
end
end
+
+ def bulk_upload_options(bulk_upload)
+ array = bulk_upload ? [bulk_upload.id] : []
+ array.index_with { |_bulk_upload_id| "With logs from bulk upload" }
+ end
end
diff --git a/app/models/log.rb b/app/models/log.rb
index 3217251b1..fcde08bdb 100644
--- a/app/models/log.rb
+++ b/app/models/log.rb
@@ -24,6 +24,10 @@ class Log < ApplicationRecord
where(created_by: user)
end
}
+ scope :filter_by_bulk_upload_id, lambda { |bulk_upload_id, user|
+ joins(:bulk_upload)
+ .where(bulk_upload: { id: bulk_upload_id, user: })
+ }
scope :created_by, ->(user) { where(created_by: user) }
def collection_start_year
diff --git a/app/models/user.rb b/app/models/user.rb
index 04a545584..4d2aeeca1 100644
--- a/app/models/user.rb
+++ b/app/models/user.rb
@@ -145,9 +145,9 @@ class User < ApplicationRecord
def logs_filters(specific_org: false)
if (support? && !specific_org) || organisation.has_managing_agents?
- %w[status years user organisation]
+ %w[status years user organisation bulk_upload_id]
else
- %w[status years user]
+ %w[status years user bulk_upload_id]
end
end
diff --git a/app/views/bulk_upload_lettings_results/resume.html.erb b/app/views/bulk_upload_lettings_results/resume.html.erb
new file mode 100644
index 000000000..a5af1bd9d
--- /dev/null
+++ b/app/views/bulk_upload_lettings_results/resume.html.erb
@@ -0,0 +1,11 @@
+
+
+
There are no more logs that need updating
+
+
+
+
+ You’ve completed all the logs that had errors from your bulk upload.
+
+
+<%= govuk_button_link_to "Back to all logs", lettings_logs_path, button: true %>
diff --git a/app/views/logs/_log_filters.erb b/app/views/logs/_log_filters.erb
index d2a327d99..8fb4f2ba4 100644
--- a/app/views/logs/_log_filters.erb
+++ b/app/views/logs/_log_filters.erb
@@ -3,13 +3,48 @@
+
<%= form_with html: { method: :get } do |f| %>
- <% years = {"2021": "2021/22", "2022": "2022/23"} %>
- <% all_or_yours = {"all": { label: "All" }, "yours": { label: "Yours" } } %>
- <%= render partial: "filters/checkbox_filter", locals: { f: f, options: years, label: "Collection year", category: "years" } %>
- <%= render partial: "filters/checkbox_filter", locals: { f: f, options: status_filters, label: "Status", category: "status" } %>
- <%= render partial: "filters/radio_filter", locals: { f: f, options: all_or_yours, label: "Logs", category: "user", } %>
+ <% years = { "2021": "2021/22", "2022": "2022/23" } %>
+ <% all_or_yours = { "all": { label: "All" }, "yours": { label: "Yours" } } %>
+
+ <% if bulk_upload_options(@bulk_upload).present? %>
+ <%= render partial: "filters/checkbox_filter",
+ locals: {
+ f: f,
+ options: bulk_upload_options(@bulk_upload),
+ label: "Bulk upload",
+ category: "bulk_upload_id",
+ } %>
+ <% end %>
+
+ <% if bulk_upload_options(@bulk_upload).blank? %>
+ <%= render partial: "filters/checkbox_filter",
+ locals: {
+ f: f,
+ options: years,
+ label: "Collection year",
+ category: "years",
+ } %>
+
+ <%= render partial: "filters/checkbox_filter",
+ locals: {
+ f: f,
+ options: status_filters,
+ label: "Status",
+ category: "status",
+ } %>
+ <% end %>
+
+ <%= render partial: "filters/radio_filter",
+ locals: {
+ f: f,
+ options: all_or_yours,
+ label: "Logs",
+ category: "user",
+ } %>
+
<% if (@current_user.support? || @current_user.organisation.has_managing_agents?) && request.path == "/lettings-logs" %>
<%= render partial: "filters/radio_filter", locals: {
f: f,
@@ -21,14 +56,15 @@
type: "select",
label: "Organisation",
category: "organisation",
- options: organisations_filter_options(@current_user)
- }
- }
+ options: organisations_filter_options(@current_user),
+ },
+ },
},
label: "Organisation",
- category: "organisation_select"
+ category: "organisation_select",
} %>
<% end %>
+
<%= f.govuk_submit "Apply filters", class: "govuk-!-margin-bottom-0" %>
<% end %>
diff --git a/app/views/logs/index.html.erb b/app/views/logs/index.html.erb
index 3f0d2031d..31768c731 100644
--- a/app/views/logs/index.html.erb
+++ b/app/views/logs/index.html.erb
@@ -11,32 +11,58 @@
title_id: "impacted-logs-banner",
) do |notification_banner| %>
<% notification_banner.heading(text: "A scheme has changed and it has affected #{@unresolved_count} #{'log'.pluralize(@unresolved_count)}") %>
-
- <%= govuk_link_to "Update logs", update_logs_lettings_logs_path, class: "govuk-notification-banner__link" %>
-
- <% end %>
+
+ <%= govuk_link_to "Update logs", update_logs_lettings_logs_path, class: "govuk-notification-banner__link" %>
+
<% end %>
- <%= render partial: "organisations/headings", locals: current_user.support? ? { main: "Lettings logs", sub: nil } : { main: "Lettings logs", sub: current_user.organisation.name } %>
-<% elsif current_page?(controller: 'sales_logs', action: 'index') %>
- <%= render partial: "organisations/headings", locals: current_user.support? ? { main: "Sales logs", sub: nil } : { main: "Sales logs", sub: current_user.organisation.name } %>
+ <% end %>
<% end %>
-
-
- <% if current_page?(controller: 'lettings_logs', action: 'index') %>
- <%= govuk_button_to "Create a new lettings log", lettings_logs_path, class: "govuk-!-margin-right-6" %>
- <% end %>
+<% if @bulk_upload.blank? %>
+ <%= render partial: "organisations/headings", locals: current_user.support? ? { main: "#{log_type_for_controller(controller).capitalize} logs", sub: nil } : { main: "#{log_type_for_controller(controller).capitalize} logs", sub: current_user.organisation.name } %>
+<% else %>
+ <%= render partial: "organisations/headings",
+ locals: {
+ main: "You need to fix #{pluralize(@pagy.count, 'log')} from your bulk upload",
+ sub: "#{log_type_for_controller(controller).capitalize} logs (#{@bulk_upload.year_combo})",
+ } %>
- <% if FeatureToggle.sales_log_enabled? && current_page?(controller: 'sales_logs', action: 'index') %>
- <%= govuk_button_to "Create a new sales log", sales_logs_path, class: "govuk-!-margin-right-6" %>
- <% end %>
+
+
+
+
+ The following logs are from your recent bulk upload. They have some incorrect or incomplete data. You’ll need to answer a few more questions for each one to mark them as complete.
+
- <% if FeatureToggle.bulk_upload_logs? %>
- <%= govuk_button_link_to "Upload #{log_type_for_controller(controller)} logs in bulk", bulk_upload_path_for_controller(controller, id: "start"), secondary: true %>
- <% end %>
+
+ Bulk Upload details:
+ <%= @bulk_upload.filename %>
+ Uploaded on <%= @bulk_upload.created_at.to_fs(:govuk_date_and_time) %>
+
+
+
+<% end %>
+
+
+ <% unless @bulk_upload %>
+
+ <% if current_page?(controller: 'lettings_logs', action: 'index') %>
+ <%= govuk_button_to "Create a new lettings log", lettings_logs_path, class: "govuk-!-margin-right-6" %>
+ <% end %>
+
+ <% if FeatureToggle.sales_log_enabled? && current_page?(controller: 'sales_logs', action: 'index') %>
+ <%= govuk_button_to "Create a new sales log", sales_logs_path, class: "govuk-!-margin-right-6" %>
+ <% end %>
+
+ <% if FeatureToggle.bulk_upload_logs? %>
+ <%= govuk_button_link_to "Upload #{log_type_for_controller(controller)} logs in bulk", bulk_upload_path_for_controller(controller, id: "start"), secondary: true %>
+ <% end %>
+
+ <% end %>
<%= render partial: "log_filters" %>
+
<%= render SearchComponent.new(current_user:, search_label: "Search by log ID, tenant code, property reference or postcode", value: @searched) %>
<%= govuk_section_break(visible: true, size: "m") %>
diff --git a/config/routes.rb b/config/routes.rb
index 4e5b224c1..913212dd2 100644
--- a/config/routes.rb
+++ b/config/routes.rb
@@ -134,7 +134,11 @@ Rails.application.routes.draw do
end
end
- resources :bulk_upload_lettings_results, path: "bulk-upload-results", only: [:show]
+ resources :bulk_upload_lettings_results, path: "bulk-upload-results", only: [:show] do
+ member do
+ get :resume
+ end
+ end
get "update-logs", to: "lettings_logs#update_logs"
end
diff --git a/spec/controllers/bulk_upload_lettings_results_controller_spec.rb b/spec/controllers/bulk_upload_lettings_results_controller_spec.rb
new file mode 100644
index 000000000..7fb50a76a
--- /dev/null
+++ b/spec/controllers/bulk_upload_lettings_results_controller_spec.rb
@@ -0,0 +1,68 @@
+require "rails_helper"
+
+RSpec.describe BulkUploadLettingsResultsController do
+ before do
+ sign_in user
+ end
+
+ describe "GET #resume /lettings-logs/bulk-upload-results/:ID/resume" do
+ let(:user) { create(:user) }
+ let(:bulk_upload) { create(:bulk_upload, :lettings, user:) }
+
+ context "when there are no logs left to resolve" do
+ render_views
+
+ it "displays copy to user" do
+ get :resume, params: { id: bulk_upload.id }
+
+ expect(response.body).to include("There are no more logs that need updating")
+ end
+
+ it "resets logs filters" do
+ get :resume, params: { id: bulk_upload.id }
+
+ expect(JSON.parse(session["logs_filters"])).to eql({})
+ end
+ end
+
+ context "when there are logs left to resolve" do
+ before do
+ create(:lettings_log, :in_progress, bulk_upload:)
+ end
+
+ it "clears the year filter" do
+ hash = {
+ years: ["", "2022"],
+ }
+
+ session["logs_filters"] = hash.to_json
+
+ get :resume, params: { id: bulk_upload.id }
+
+ expect(JSON.parse(session["logs_filters"])["years"]).to eql([""])
+ end
+
+ it "sets the status filter to in progress" do
+ session["logs_filters"] ||= {}.to_json
+
+ get :resume, params: { id: bulk_upload.id }
+
+ expect(JSON.parse(session["logs_filters"])["status"]).to eql(["", "in_progress"])
+ end
+
+ it "sets the user filter to all" do
+ session["logs_filters"] ||= {}.to_json
+
+ get :resume, params: { id: bulk_upload.id }
+
+ expect(JSON.parse(session["logs_filters"])["user"]).to eql("all")
+ end
+
+ it "redirects to logs with bulk upload filter applied" do
+ get :resume, params: { id: bulk_upload.id }
+
+ expect(response).to redirect_to("/lettings-logs?bulk_upload_id%5B%5D=#{bulk_upload.id}")
+ end
+ end
+ end
+end
diff --git a/spec/models/user_spec.rb b/spec/models/user_spec.rb
index 9244ad7e5..b285a55e7 100644
--- a/spec/models/user_spec.rb
+++ b/spec/models/user_spec.rb
@@ -123,7 +123,7 @@ RSpec.describe User, type: :model do
end
it "can filter lettings logs by user, year and status" do
- expect(user.logs_filters).to eq(%w[status years user])
+ expect(user.logs_filters).to eq(%w[status years user bulk_upload_id])
end
end
@@ -133,7 +133,7 @@ RSpec.describe User, type: :model do
end
it "can filter lettings logs by user, year, status and organisation" do
- expect(user.logs_filters).to eq(%w[status years user organisation])
+ expect(user.logs_filters).to eq(%w[status years user organisation bulk_upload_id])
end
end
end
@@ -159,7 +159,7 @@ RSpec.describe User, type: :model do
end
it "can filter lettings logs by user, year, status and organisation" do
- expect(user.logs_filters).to eq(%w[status years user organisation])
+ expect(user.logs_filters).to eq(%w[status years user organisation bulk_upload_id])
end
end
diff --git a/spec/requests/lettings_logs_controller_spec.rb b/spec/requests/lettings_logs_controller_spec.rb
index 9565f08ec..1bb0afbf9 100644
--- a/spec/requests/lettings_logs_controller_spec.rb
+++ b/spec/requests/lettings_logs_controller_spec.rb
@@ -400,6 +400,109 @@ RSpec.describe LettingsLogsController, type: :request do
expect(page).not_to have_link(lettings_log_2022.id.to_s)
end
end
+
+ context "with bulk_upload_id filter" do
+ context "with bulk upload that belongs to current user" do
+ let(:organisation) { create(:organisation) }
+
+ let(:user) { create(:user, organisation:) }
+ let(:bulk_upload) { create(:bulk_upload, user:) }
+
+ let!(:included_log) { create(:lettings_log, :in_progress, bulk_upload:, owning_organisation: organisation) }
+ let!(:excluded_log) { create(:lettings_log, :in_progress, owning_organisation: organisation) }
+
+ it "returns logs only associated with the bulk upload" do
+ get "/lettings-logs?bulk_upload_id[]=#{bulk_upload.id}"
+
+ expect(page).to have_content(included_log.id)
+ expect(page).not_to have_content(excluded_log.id)
+ end
+
+ it "dislays how many logs remaining to fix" do
+ get "/lettings-logs?bulk_upload_id[]=#{bulk_upload.id}"
+ expect(page).to have_content("You need to fix 1 log")
+ end
+
+ it "displays filter" do
+ get "/lettings-logs?bulk_upload_id[]=#{bulk_upload.id}"
+ expect(page).to have_content("With logs from bulk upload")
+ end
+
+ it "hides collection year filter" do
+ get "/lettings-logs?bulk_upload_id[]=#{bulk_upload.id}"
+ expect(page).not_to have_content("Collection year")
+ end
+
+ it "hides status filter" do
+ get "/lettings-logs?bulk_upload_id[]=#{bulk_upload.id}"
+ expect(page).not_to have_content("Status")
+ end
+
+ it "hides button to create a new log" do
+ get "/lettings-logs?bulk_upload_id[]=#{bulk_upload.id}"
+ expect(page).not_to have_content("Create a new lettings log")
+ end
+
+ it "displays card with help info" do
+ get "/lettings-logs?bulk_upload_id[]=#{bulk_upload.id}"
+ expect(page).to have_content("The following logs are from your recent bulk upload")
+ end
+
+ it "displays meta info about the bulk upload" do
+ get "/lettings-logs?bulk_upload_id[]=#{bulk_upload.id}"
+ expect(page).to have_content(bulk_upload.filename)
+ expect(page).to have_content(bulk_upload.created_at.to_fs(:govuk_date_and_time))
+ end
+ end
+
+ context "with bulk upload that belongs to another user" do
+ let(:organisation) { create(:organisation) }
+
+ let(:user) { create(:user, organisation:) }
+ let(:other_user) { create(:user, organisation:) }
+ let(:bulk_upload) { create(:bulk_upload, user: other_user) }
+
+ let!(:excluded_log) { create(:lettings_log, bulk_upload:, owning_organisation: organisation) }
+ let!(:also_excluded_log) { create(:lettings_log, owning_organisation: organisation) }
+
+ it "does not return any logs" do
+ get "/lettings-logs?bulk_upload_id[]=#{bulk_upload.id}"
+
+ expect(page).not_to have_content(excluded_log.id)
+ expect(page).not_to have_content(also_excluded_log.id)
+ end
+ end
+
+ context "when bulk upload has been resolved" do
+ let(:organisation) { create(:organisation) }
+
+ let(:user) { create(:user, organisation:) }
+ let(:bulk_upload) { create(:bulk_upload, user:) }
+
+ it "redirects to resume the bulk upload" do
+ get "/lettings-logs?bulk_upload_id[]=#{bulk_upload.id}"
+
+ expect(response).to redirect_to(resume_bulk_upload_lettings_result_path(bulk_upload))
+ end
+ end
+ end
+
+ context "without bulk_upload_id" do
+ it "does not display filter" do
+ get "/lettings-logs"
+ expect(page).not_to have_content("With logs from bulk upload")
+ end
+
+ it "displays button to create a new log" do
+ get "/lettings-logs"
+ expect(page).to have_content("Create a new lettings log")
+ end
+
+ it "does not display card with help info" do
+ get "/lettings-logs"
+ expect(page).not_to have_content("The following logs are from your recent bulk upload")
+ end
+ end
end
end
diff --git a/spec/support/bulk_upload/log_to_csv.rb b/spec/support/bulk_upload/log_to_csv.rb
index 3b49f0b86..7734d9fe2 100644
--- a/spec/support/bulk_upload/log_to_csv.rb
+++ b/spec/support/bulk_upload/log_to_csv.rb
@@ -159,12 +159,7 @@ class BulkUpload::LogToCsv
end
def renewal
- case log.renewal
- when 1
- 1
- when 0
- 2
- end
+ checkbox_value(log.renewal)
end
def london_affordable_rent
@@ -210,12 +205,7 @@ class BulkUpload::LogToCsv
end
def previous_postcode_known
- case log.ppcodenk
- when 1
- 1
- when 0
- 2
- end
+ checkbox_value(log.ppcodenk)
end
def homeless
@@ -228,25 +218,19 @@ class BulkUpload::LogToCsv
end
def cbl
- case log.cbl
- when 0
- 2
- when 1
- 1
- end
+ checkbox_value(log.cbl)
end
def chr
- case log.chr
- when 0
- 2
- when 1
- 1
- end
+ checkbox_value(log.chr)
end
def cap
- case log.cap
+ checkbox_value(log.cap)
+ end
+
+ def checkbox_value(field)
+ case field
when 0
2
when 1