Browse Source

Filter schemes

pull/1796/head
Kat 3 years ago
parent
commit
4e06fed0f3
  1. 9
      app/controllers/organisations_controller.rb
  2. 13
      app/controllers/schemes_controller.rb
  3. 46
      app/models/scheme.rb
  4. 17
      app/services/filter_manager.rb
  5. 4
      spec/factories/scheme.rb
  6. 68
      spec/models/scheme_spec.rb
  7. 110
      spec/requests/schemes_controller_spec.rb

9
app/controllers/organisations_controller.rb

@ -5,9 +5,9 @@ class OrganisationsController < ApplicationController
before_action :authenticate_user!
before_action :find_resource, except: %i[index new create]
before_action :authenticate_scope!, except: [:index]
before_action :session_filters, if: -> { current_user.support? || current_user.organisation.has_managing_agents? }, only: %i[lettings_logs sales_logs email_lettings_csv download_lettings_csv email_sales_csv download_sales_csv]
before_action :session_filters, if: -> { current_user.support? || current_user.organisation.has_managing_agents? }, only: %i[lettings_logs sales_logs email_lettings_csv download_lettings_csv email_sales_csv download_sales_csv schemes]
before_action :session_filters, only: %i[users]
before_action -> { filter_manager.serialize_filters_to_session }, if: -> { current_user.support? || current_user.organisation.has_managing_agents? }, only: %i[lettings_logs sales_logs email_lettings_csv download_lettings_csv email_sales_csv download_sales_csv]
before_action -> { filter_manager.serialize_filters_to_session }, if: -> { current_user.support? || current_user.organisation.has_managing_agents? }, only: %i[lettings_logs sales_logs email_lettings_csv download_lettings_csv email_sales_csv download_sales_csv schemes]
before_action -> { filter_manager.serialize_filters_to_session }, only: %i[users]
def index
@ -22,9 +22,10 @@ class OrganisationsController < ApplicationController
def schemes
all_schemes = Scheme.where(owning_organisation: [@organisation] + @organisation.parent_organisations).order_by_completion.order_by_service_name
@pagy, @schemes = pagy(filtered_collection(all_schemes, search_term))
@pagy, @schemes = pagy(filter_manager.filtered_schemes(all_schemes, search_term, session_filters))
@searched = search_term.presence
@total_count = all_schemes.size
@filter_type = "schemes"
end
def show
@ -209,6 +210,8 @@ private
"sales_logs"
elsif params[:action].include?("users")
"users"
elsif params[:action].include?("schemes")
"schemes"
end
end

13
app/controllers/schemes_controller.rb

@ -6,6 +6,8 @@ class SchemesController < ApplicationController
before_action :find_resource, except: %i[index create new]
before_action :redirect_if_scheme_confirmed, only: %i[primary_client_group confirm_secondary_client_group secondary_client_group support details]
before_action :authorize_user
before_action :session_filters, if: :current_user, only: %i[index]
before_action -> { filter_manager.serialize_filters_to_session }, if: :current_user, only: %i[index]
rescue_from ActiveRecord::RecordNotFound, with: :render_not_found
@ -13,9 +15,10 @@ class SchemesController < ApplicationController
redirect_to schemes_organisation_path(current_user.organisation) unless current_user.support?
all_schemes = Scheme.order_by_completion.order_by_service_name
@pagy, @schemes = pagy(filtered_collection(all_schemes, search_term))
@pagy, @schemes = pagy(filter_manager.filtered_schemes(all_schemes, search_term, session_filters))
@searched = search_term.presence
@total_count = all_schemes.size
@filter_type = "schemes"
end
def show
@ -336,4 +339,12 @@ private
logs.update!(location: nil, scheme: nil, unresolved: true)
logs
end
def filter_manager
FilterManager.new(current_user:, session:, params:, filter_type: "schemes")
end
def session_filters
filter_manager.session_filters
end
end

46
app/models/scheme.rb

@ -19,6 +19,52 @@ class Scheme < ApplicationRecord
scope :order_by_completion, -> { order("confirmed ASC NULLS FIRST") }
scope :order_by_service_name, -> { order(service_name: :asc) }
scope :filter_by_status, lambda { |statuses, _user = nil|
filtered_records = all
scopes = []
statuses.each do |status|
status = status == "active" ? "active_status" : status
if respond_to?(status, true)
scopes << send(status)
end
end
if scopes.any?
filtered_records = filtered_records
.left_outer_joins(:scheme_deactivation_periods)
.order("scheme_deactivation_periods.created_at DESC")
.merge(scopes.reduce(&:or))
end
filtered_records
}
scope :incomplete, lambda {
where.not(confirmed: true)
}
scope :deactivated, lambda {
merge(SchemeDeactivationPeriod.deactivations_without_reactivation)
.where("scheme_deactivation_periods.deactivation_date <= ?", Time.zone.now)
}
scope :deactivating_soon, lambda {
merge(SchemeDeactivationPeriod.deactivations_without_reactivation)
.where("scheme_deactivation_periods.deactivation_date > ?", Time.zone.now)
}
scope :reactivating_soon, lambda {
where.not("scheme_deactivation_periods.reactivation_date IS NULL")
.where("scheme_deactivation_periods.reactivation_date > ?", Time.zone.now)
}
scope :active_status, lambda {
where.not(id: joins(:scheme_deactivation_periods).reactivating_soon.pluck(:id))
.where.not(id: joins(:scheme_deactivation_periods).deactivated.pluck(:id))
.where.not(id: incomplete.pluck(:id))
.where.not(id: joins(:scheme_deactivation_periods).deactivating_soon.pluck(:id))
}
validate :validate_confirmed
validate :validate_owning_organisation

17
app/services/filter_manager.rb

@ -50,6 +50,17 @@ class FilterManager
users
end
def self.filter_schemes(schemes, search_term, filters, user)
schemes = filter_by_search(schemes, search_term)
filters.each do |category, values|
next if Array(values).reject(&:empty?).blank?
schemes = schemes.public_send("filter_by_#{category}", values, user)
end
schemes.order(created_at: :desc)
end
def serialize_filters_to_session(specific_org: false)
session[session_name_for(filter_type)] = session_filters(specific_org:).to_json
end
@ -73,7 +84,7 @@ class FilterManager
new_filters["user"] = current_user.id.to_s if params["assigned_to"] == "you"
end
if @filter_type.include?("users") && params["status"].present?
if (@filter_type.include?("schemes") || @filter_type.include?("users")) && params["status"].present?
new_filters["status"] = params["status"]
end
@ -90,6 +101,10 @@ class FilterManager
FilterManager.filter_users(users, search_term, filters, current_user)
end
def filtered_schemes(schemes, search_term, filters)
FilterManager.filter_schemes(schemes, search_term, filters, current_user)
end
def bulk_upload
id = (logs_filters["bulk_upload_id"] || []).reject(&:blank?)[0]
@bulk_upload ||= current_user.bulk_uploads.find_by(id:)

4
spec/factories/scheme.rb

@ -25,5 +25,9 @@ FactoryBot.define do
trait :with_old_visible_id do
old_visible_id { rand(9_999_999) }
end
trait :incomplete do
confirmed { false }
support_type { nil }
end
end
end

68
spec/models/scheme_spec.rb

@ -89,6 +89,74 @@ RSpec.describe Scheme, type: :model do
expect(described_class.search_by(location.name.downcase).first.locations.first.name).to eq(location.name)
end
end
context "when filtering by status" do
let!(:incomplete_scheme) { FactoryBot.create(:scheme, :incomplete) }
let!(:active_scheme) { FactoryBot.create(:scheme) }
let(:deactivating_soon_scheme) { FactoryBot.create(:scheme) }
let(:deactivated_scheme) { FactoryBot.create(:scheme) }
let(:reactivating_soon_scheme) { FactoryBot.create(:scheme) }
before do
scheme.destroy!
scheme_1.destroy!
scheme_2.destroy!
Timecop.freeze(2022, 6, 7)
FactoryBot.create(:scheme_deactivation_period, deactivation_date: Time.zone.local(2022, 8, 8), scheme: deactivating_soon_scheme)
deactivating_soon_scheme.save!
FactoryBot.create(:scheme_deactivation_period, deactivation_date: Time.zone.local(2022, 6, 6), scheme: deactivated_scheme)
deactivated_scheme.save!
FactoryBot.create(:scheme_deactivation_period, deactivation_date: Time.zone.local(2022, 6, 7), reactivation_date: Time.zone.local(2022, 6, 8), scheme: reactivating_soon_scheme)
reactivating_soon_scheme.save!
end
after do
Timecop.unfreeze
end
context "when filtering by incomplete status" do
it "returns only incomplete schemes" do
expect(described_class.filter_by_status(%w[incomplete]).count).to eq(1)
expect(described_class.filter_by_status(%w[incomplete]).first).to eq(incomplete_scheme)
end
end
context "when filtering by active status" do
it "returns only active schemes" do
expect(described_class.filter_by_status(%w[active]).count).to eq(1)
expect(described_class.filter_by_status(%w[active]).first).to eq(active_scheme)
end
end
context "when filtering by deactivating_soon status" do
it "returns only deactivating_soon schemes" do
expect(described_class.filter_by_status(%w[deactivating_soon]).count).to eq(1)
expect(described_class.filter_by_status(%w[deactivating_soon]).first).to eq(deactivating_soon_scheme)
end
end
context "when filtering by deactivated status" do
it "returns only deactivated schemes" do
expect(described_class.filter_by_status(%w[deactivated]).count).to eq(1)
expect(described_class.filter_by_status(%w[deactivated]).first).to eq(deactivated_scheme)
end
end
context "when filtering by reactivating_soon status" do
it "returns only reactivating_soon schemes" do
expect(described_class.filter_by_status(%w[reactivating_soon]).count).to eq(1)
expect(described_class.filter_by_status(%w[reactivating_soon]).first).to eq(reactivating_soon_scheme)
end
end
context "when filtering by multiple statuses" do
it "returns relevant schemes" do
expect(described_class.filter_by_status(%w[deactivating_soon reactivating_soon]).count).to eq(2)
expect(described_class.filter_by_status(%w[deactivating_soon reactivating_soon])).to include(reactivating_soon_scheme)
expect(described_class.filter_by_status(%w[deactivating_soon reactivating_soon])).to include(deactivating_soon_scheme)
end
end
end
end
end

110
spec/requests/schemes_controller_spec.rb

@ -75,6 +75,64 @@ RSpec.describe SchemesController, type: :request do
end
end
end
context "when filtering" do
context "with status filter" do
let!(:incomplete_scheme) { create(:scheme, :incomplete, owning_organisation: user.organisation) }
let!(:active_scheme) { create(:scheme, owning_organisation: user.organisation) }
let!(:deactivated_scheme) { create(:scheme, owning_organisation: user.organisation) }
before do
create(:scheme_deactivation_period, scheme: deactivated_scheme, deactivation_date: Time.zone.local(2022, 4, 1))
end
it "shows schemes for multiple selected statuses" do
get "/schemes?status[]=incomplete&status[]=active", headers:, params: {}
follow_redirect!
expect(page).to have_link(incomplete_scheme.service_name)
expect(page).to have_link(active_scheme.service_name)
expect(page).not_to have_link(deactivated_scheme.service_name)
end
it "shows filtered incomplete schemes" do
get "/schemes?status[]=incomplete", headers:, params: {}
follow_redirect!
expect(page).to have_link(incomplete_scheme.service_name)
expect(page).not_to have_link(active_scheme.service_name)
expect(page).not_to have_link(deactivated_scheme.service_name)
end
it "shows filtered active schemes" do
get "/schemes?status[]=active", headers:, params: {}
follow_redirect!
expect(page).to have_link(active_scheme.service_name)
expect(page).not_to have_link(incomplete_scheme.service_name)
expect(page).not_to have_link(deactivated_scheme.service_name)
end
it "shows filtered deactivated schemes" do
get "/schemes?status[]=deactivated", headers:, params: {}
follow_redirect!
expect(page).to have_link(deactivated_scheme.service_name)
expect(page).not_to have_link(active_scheme.service_name)
expect(page).not_to have_link(incomplete_scheme.service_name)
end
it "does not reset the filters" do
get "/schemes?status[]=incomplete", headers:, params: {}
follow_redirect!
expect(page).to have_link(incomplete_scheme.service_name)
expect(page).not_to have_link(active_scheme.service_name)
expect(page).not_to have_link(deactivated_scheme.service_name)
get "/schemes", headers:, params: {}
follow_redirect!
expect(page).to have_link(incomplete_scheme.service_name)
expect(page).not_to have_link(active_scheme.service_name)
expect(page).not_to have_link(deactivated_scheme.service_name)
end
end
end
end
context "when signed in as a support user" do
@ -221,6 +279,58 @@ RSpec.describe SchemesController, type: :request do
expect(page).to have_title("Supported housing schemes (1 scheme matching ‘#{search_param}’) - Submit social housing lettings and sales data (CORE) - GOV.UK")
end
end
context "when filtering" do
context "with status filter" do
let!(:incomplete_scheme) { create(:scheme, :incomplete) }
let!(:active_scheme) { create(:scheme) }
let!(:deactivated_scheme) { create(:scheme) }
before do
create(:scheme_deactivation_period, scheme: deactivated_scheme, deactivation_date: Time.zone.local(2022, 4, 1))
end
it "shows schemes for multiple selected statuses" do
get "/schemes?status[]=incomplete&status[]=active", headers:, params: {}
expect(page).to have_link(incomplete_scheme.service_name)
expect(page).to have_link(active_scheme.service_name)
expect(page).not_to have_link(deactivated_scheme.service_name)
end
it "shows filtered incomplete schemes" do
get "/schemes?status[]=incomplete", headers:, params: {}
expect(page).to have_link(incomplete_scheme.service_name)
expect(page).not_to have_link(active_scheme.service_name)
expect(page).not_to have_link(deactivated_scheme.service_name)
end
it "shows filtered active schemes" do
get "/schemes?status[]=active", headers:, params: {}
expect(page).to have_link(active_scheme.service_name)
expect(page).not_to have_link(incomplete_scheme.service_name)
expect(page).not_to have_link(deactivated_scheme.service_name)
end
it "shows filtered deactivated schemes" do
get "/schemes?status[]=deactivated", headers:, params: {}
expect(page).to have_link(deactivated_scheme.service_name)
expect(page).not_to have_link(active_scheme.service_name)
expect(page).not_to have_link(incomplete_scheme.service_name)
end
it "does not reset the filters" do
get "/schemes?status[]=incomplete", headers:, params: {}
expect(page).to have_link(incomplete_scheme.service_name)
expect(page).not_to have_link(active_scheme.service_name)
expect(page).not_to have_link(deactivated_scheme.service_name)
get "/schemes", headers:, params: {}
expect(page).to have_link(incomplete_scheme.service_name)
expect(page).not_to have_link(active_scheme.service_name)
expect(page).not_to have_link(deactivated_scheme.service_name)
end
end
end
end
end

Loading…
Cancel
Save