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 @@

Filters

+
<%= 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