Browse Source

CLDC-1764 Bulk upload filter (#1223)

* refactor with extract method

* can filter logs by bulk upload

* hide log creation button when viewing bulk upload

- this affects the logs index page filtering logs from a specific bulk
  upload

* add info banner to bulk upload logs

* placeholder for bulk upload logs header

* when resuming bulk upload set filters

* fill place holder with remaining logs to fix

* add interstitial to resume if logs resolved

* after resolving bulk upload logs show interstitial

* fix linting error

* extract view variable to helper method
pull/1239/head v0.2.35
Phil Lee 2 years ago committed by GitHub
parent
commit
9513e1179d
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
  1. 28
      app/controllers/bulk_upload_lettings_results_controller.rb
  2. 14
      app/controllers/lettings_logs_controller.rb
  3. 4
      app/controllers/modules/logs_filter.rb
  4. 5
      app/helpers/logs_helper.rb
  5. 4
      app/models/log.rb
  6. 4
      app/models/user.rb
  7. 11
      app/views/bulk_upload_lettings_results/resume.html.erb
  8. 54
      app/views/logs/_log_filters.erb
  9. 32
      app/views/logs/index.html.erb
  10. 6
      config/routes.rb
  11. 68
      spec/controllers/bulk_upload_lettings_results_controller_spec.rb
  12. 6
      spec/models/user_spec.rb
  13. 103
      spec/requests/lettings_logs_controller_spec.rb
  14. 34
      spec/support/bulk_upload/log_to_csv.rb

28
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

14
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

4
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

5
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

4
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

4
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

11
app/views/bulk_upload_lettings_results/resume.html.erb

@ -0,0 +1,11 @@
<div class="govuk-grid-row">
<div class="govuk-grid-column-two-thirds">
<h1 class="govuk-heading-xl">There are no more logs that need updating</h1>
</div>
</div>
<p class="govuk-body-l">
You’ve completed all the logs that had errors from your bulk upload.
</p>
<%= govuk_button_link_to "Back to all logs", lettings_logs_path, button: true %>

54
app/views/logs/_log_filters.erb

@ -3,13 +3,48 @@
<div class="app-filter__header">
<h2 class="govuk-heading-m">Filters</h2>
</div>
<div class="app-filter__content">
<%= 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 %>
</div>

32
app/views/logs/index.html.erb

@ -16,12 +16,36 @@
</div>
<% end %>
<% 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 %>
<% 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})",
} %>
<div class="app-card govuk-!-margin-bottom-9">
<div class="govuk-grid-row">
<div class="govuk-grid-column-two-thirds">
<p class="govuk-body-l">
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.
</p>
<p class="govuk-body">
<strong>Bulk Upload details:</strong><br>
<%= @bulk_upload.filename %><br>
Uploaded on <%= @bulk_upload.created_at.to_fs(:govuk_date_and_time) %><br>
</p>
</div>
</div>
</div>
<% end %>
<div class="app-filter-layout" data-controller="filter-layout">
<% unless @bulk_upload %>
<div class="govuk-button-group app-filter-toggle govuk-!-margin-bottom-6">
<% if current_page?(controller: 'lettings_logs', action: 'index') %>
<%= govuk_button_to "Create a new lettings log", lettings_logs_path, class: "govuk-!-margin-right-6" %>
@ -35,8 +59,10 @@
<%= govuk_button_link_to "Upload #{log_type_for_controller(controller)} logs in bulk", bulk_upload_path_for_controller(controller, id: "start"), secondary: true %>
<% end %>
</div>
<% end %>
<%= render partial: "log_filters" %>
<div class="app-filter-layout__content">
<%= 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") %>

6
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

68
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

6
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

103
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

34
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

Loading…
Cancel
Save