Browse Source

CLDC 2954 handle schemes with only deactivated locations (#2510)

pull/2537/head
Manny Dinssa 5 months ago committed by GitHub
parent
commit
9b0cbac406
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
  1. 27
      app/models/location.rb
  2. 10
      app/models/scheme.rb
  3. 19
      app/models/validations/setup_validations.rb
  4. 9
      app/models/validations/shared_validations.rb
  5. 7
      app/views/schemes/_scheme_list.html.erb
  6. 3
      app/views/schemes/show.html.erb
  7. 7
      config/locales/en.yml
  8. 79
      spec/models/validations/setup_validations_spec.rb

27
app/models/location.rb

@ -22,7 +22,6 @@ class Location < ApplicationRecord
scope :search_by_name, ->(name) { where("name ILIKE ?", "%#{name}%") } scope :search_by_name, ->(name) { where("name ILIKE ?", "%#{name}%") }
scope :search_by, ->(param) { search_by_name(param).or(search_by_postcode(param)) } scope :search_by, ->(param) { search_by_name(param).or(search_by_postcode(param)) }
scope :started, -> { where("locations.startdate <= ?", Time.zone.today).or(where(startdate: nil)) } scope :started, -> { where("locations.startdate <= ?", Time.zone.today).or(where(startdate: nil)) }
scope :active, -> { where(confirmed: true).and(started) }
scope :started_in_2_weeks, -> { where("locations.startdate <= ?", Time.zone.today + 2.weeks).or(where(startdate: nil)) } scope :started_in_2_weeks, -> { where("locations.startdate <= ?", Time.zone.today + 2.weeks).or(where(startdate: nil)) }
scope :active_in_2_weeks, -> { where(confirmed: true).and(started_in_2_weeks) } scope :active_in_2_weeks, -> { where(confirmed: true).and(started_in_2_weeks) }
scope :confirmed, -> { where(confirmed: true) } scope :confirmed, -> { where(confirmed: true) }
@ -62,25 +61,25 @@ class Location < ApplicationRecord
merge(Organisation.filter_by_inactive) merge(Organisation.filter_by_inactive)
} }
scope :deactivated_directly, lambda { scope :deactivated_directly, lambda { |date = Time.zone.now|
merge(LocationDeactivationPeriod.deactivations_without_reactivation) merge(LocationDeactivationPeriod.deactivations_without_reactivation)
.where("location_deactivation_periods.deactivation_date <= ?", Time.zone.now) .where("location_deactivation_periods.deactivation_date <= ?", date)
} }
scope :deactivating_soon, lambda { scope :deactivating_soon, lambda { |date = Time.zone.now|
merge(LocationDeactivationPeriod.deactivations_without_reactivation) merge(LocationDeactivationPeriod.deactivations_without_reactivation)
.where("location_deactivation_periods.deactivation_date > ?", Time.zone.now) .where("location_deactivation_periods.deactivation_date > ?", date)
.where.not(id: joins(scheme: [:owning_organisation]).deactivated_by_organisation.pluck(:id)) .where.not(id: joins(scheme: [:owning_organisation]).deactivated_by_organisation.pluck(:id))
} }
scope :reactivating_soon, lambda { scope :reactivating_soon, lambda { |date = Time.zone.now|
where.not("location_deactivation_periods.reactivation_date IS NULL") where.not("location_deactivation_periods.reactivation_date IS NULL")
.where("location_deactivation_periods.reactivation_date > ?", Time.zone.now) .where("location_deactivation_periods.reactivation_date > ?", date)
.where.not(id: joins(scheme: [:owning_organisation]).deactivated_by_organisation.pluck(:id)) .where.not(id: joins(scheme: [:owning_organisation]).deactivated_by_organisation.pluck(:id))
} }
scope :activating_soon, lambda { scope :activating_soon, lambda { |date = Time.zone.now|
where("locations.startdate > ?", Time.zone.now) where("locations.startdate > ?", date)
} }
scope :active_status, lambda { scope :active_status, lambda {
@ -92,6 +91,14 @@ class Location < ApplicationRecord
.where.not(id: activating_soon.pluck(:id)) .where.not(id: activating_soon.pluck(:id))
} }
scope :active, lambda { |date = Time.zone.now|
where.not(id: joins(:location_deactivation_periods).reactivating_soon(date).pluck(:id))
.where.not(id: joins(scheme: [:owning_organisation]).deactivated_by_organisation.pluck(:id))
.where.not(id: joins(:location_deactivation_periods).deactivated_directly(date).pluck(:id))
.where.not(id: incomplete.pluck(:id))
.where.not(id: activating_soon(date).pluck(:id))
}
scope :visible, -> { where(discarded_at: nil) } scope :visible, -> { where(discarded_at: nil) }
LOCAL_AUTHORITIES = LocalAuthority.all.map { |la| [la.name, la.code] }.to_h LOCAL_AUTHORITIES = LocalAuthority.all.map { |la| [la.name, la.code] }.to_h
@ -157,9 +164,9 @@ class Location < ApplicationRecord
return :incomplete unless confirmed return :incomplete unless confirmed
return :deactivated if scheme.owning_organisation.status_at(date) == :deactivated || return :deactivated if scheme.owning_organisation.status_at(date) == :deactivated ||
open_deactivation&.deactivation_date.present? && date >= open_deactivation.deactivation_date open_deactivation&.deactivation_date.present? && date >= open_deactivation.deactivation_date
return :activating_soon if startdate.present? && date < startdate
return :deactivating_soon if open_deactivation&.deactivation_date.present? && date < open_deactivation.deactivation_date return :deactivating_soon if open_deactivation&.deactivation_date.present? && date < open_deactivation.deactivation_date
return :reactivating_soon if last_deactivation_before(date)&.reactivation_date.present? && date < last_deactivation_before(date).reactivation_date return :reactivating_soon if last_deactivation_before(date)&.reactivation_date.present? && date < last_deactivation_before(date).reactivation_date
return :activating_soon if startdate.present? && date < startdate
:active :active
end end

10
app/models/scheme.rb

@ -295,6 +295,16 @@ class Scheme < ApplicationRecord
status == :active status == :active
end end
def has_active_locations?
locations.active.exists?
end
def has_active_locations_on_date?(date)
return false unless date
locations.active(date).exists?
end
def reactivating_soon? def reactivating_soon?
status == :reactivating_soon status == :reactivating_soon
end end

19
app/models/validations/setup_validations.rb

@ -72,15 +72,6 @@ module Validations::SetupValidations
end end
end end
def validate_location(record)
location_during_startdate_validation(record)
if record.location&.status == :incomplete
record.errors.add :location_id, :incomplete, message: I18n.t("validations.setup.location.incomplete")
record.errors.add :scheme_id, :incomplete, message: I18n.t("validations.setup.location.incomplete")
end
end
def validate_scheme_has_confirmed_locations_validation(record) def validate_scheme_has_confirmed_locations_validation(record)
return unless record.scheme return unless record.scheme
@ -95,6 +86,16 @@ module Validations::SetupValidations
end end
scheme_during_startdate_validation(record) scheme_during_startdate_validation(record)
tenancy_startdate_with_scheme_locations(record)
end
def validate_location(record)
location_during_startdate_validation(record)
if record.location&.status == :incomplete
record.errors.add :location_id, :incomplete, message: I18n.t("validations.setup.location.incomplete")
record.errors.add :scheme_id, :incomplete, message: I18n.t("validations.setup.location.incomplete")
end
end end
def validate_managing_organisation_data_sharing_agremeent_signed(record) def validate_managing_organisation_data_sharing_agremeent_signed(record)

9
app/models/validations/shared_validations.rb

@ -87,6 +87,7 @@ module Validations::SharedValidations
def scheme_during_startdate_validation(record) def scheme_during_startdate_validation(record)
scheme_inactive_status = inactive_status(record.startdate, record.scheme) scheme_inactive_status = inactive_status(record.startdate, record.scheme)
if scheme_inactive_status.present? if scheme_inactive_status.present?
date, scope, deactivation_date = scheme_inactive_status.values_at(:date, :scope, :deactivation_date) date, scope, deactivation_date = scheme_inactive_status.values_at(:date, :scope, :deactivation_date)
record.errors.add :startdate, I18n.t("validations.setup.startdate.scheme.#{scope}.startdate", name: record.scheme.service_name, date:, deactivation_date:) record.errors.add :startdate, I18n.t("validations.setup.startdate.scheme.#{scope}.startdate", name: record.scheme.service_name, date:, deactivation_date:)
@ -112,6 +113,14 @@ module Validations::SharedValidations
{ scope: status, date: date&.to_formatted_s(:govuk_date), deactivation_date: closest_reactivation&.deactivation_date&.to_formatted_s(:govuk_date) } { scope: status, date: date&.to_formatted_s(:govuk_date), deactivation_date: closest_reactivation&.deactivation_date&.to_formatted_s(:govuk_date) }
end end
def tenancy_startdate_with_scheme_locations(record)
return if record.scheme.blank? || record.startdate.blank?
return if record.scheme.has_active_locations_on_date?(record.startdate)
record.errors.add :startdate, I18n.t("validations.setup.startdate.scheme.locations_inactive.startdate", name: record.scheme.service_name)
record.errors.add :scheme_id, I18n.t("validations.setup.startdate.scheme.locations_inactive.scheme_id", name: record.scheme.service_name)
end
def shared_validate_partner_count(record, max_people) def shared_validate_partner_count(record, max_people)
return if record.form.start_year_after_2024? return if record.form.start_year_after_2024?

7
app/views/schemes/_scheme_list.html.erb

@ -26,7 +26,12 @@
<% row.with_cell(text: scheme.owning_organisation&.name) %> <% row.with_cell(text: scheme.owning_organisation&.name) %>
<% row.with_cell(text: scheme.id_to_display) %> <% row.with_cell(text: scheme.id_to_display) %>
<% row.with_cell(text: scheme.locations.visible&.count) %> <% row.with_cell(text: scheme.locations.visible&.count) %>
<% row.with_cell(text: status_tag_from_resource(scheme)) %> <% row.with_cell do %>
<%= status_tag_from_resource(scheme) %>
<% if scheme.active? && !scheme.has_active_locations? %>
<%= content_tag(:div, "No currently active locations", class: "app-!-colour-muted", style: "margin-top: 10px") %>
<% end %>
<% end %>
<% end %> <% end %>
<% end %> <% end %>
<% end %> <% end %>

3
app/views/schemes/show.html.erb

@ -26,6 +26,9 @@
<dt class="govuk-summary-list__key">Status</dt> <dt class="govuk-summary-list__key">Status</dt>
<dd class="govuk-summary-list__value"> <dd class="govuk-summary-list__value">
<%= details_html({ name: "Status", value: status_tag_from_resource(@scheme), id: "status" }) %> <%= details_html({ name: "Status", value: status_tag_from_resource(@scheme), id: "status" }) %>
<% if @scheme.confirmed? && @scheme.active? && !@scheme.has_active_locations? %>
<span class="app-!-colour-muted">No currently active locations</span>
<% end %>
<% if @scheme.confirmed? && @scheme.locations.confirmed.none? && LocationPolicy.new(current_user, @scheme.locations.new).create? %> <% if @scheme.confirmed? && @scheme.locations.confirmed.none? && LocationPolicy.new(current_user, @scheme.locations.new).create? %>
<span class="app-!-colour-muted">Complete this scheme by adding a location using the <%= govuk_link_to("‘locations’ tab", scheme_locations_path(@scheme)) %>.</span> <span class="app-!-colour-muted">Complete this scheme by adding a location using the <%= govuk_link_to("‘locations’ tab", scheme_locations_path(@scheme)) %>.</span>
<% end %> <% end %>

7
config/locales/en.yml

@ -286,8 +286,8 @@ en:
location: location:
deactivated: deactivated:
startdate: "The location %{postcode} was deactivated on %{date} and was not available on the day you entered. Select another location or edit the tenancy start date" startdate: "The location %{postcode} is inactive on this date. Enter another date or choose another location."
location_id: "The location %{postcode} was deactivated on %{date} and was not available on the day you entered. Select another location or edit the tenancy start date" location_id: "This location is not active on the tenancy start date. Choose another location or edit the tenancy start date."
activating_soon: activating_soon:
startdate: "The location %{postcode} is not available until %{date}. Enter a tenancy start date after %{date}" startdate: "The location %{postcode} is not available until %{date}. Enter a tenancy start date after %{date}"
location_id: "The location %{postcode} is not available until %{date}. Select another location or edit the tenancy start date" location_id: "The location %{postcode} is not available until %{date}. Select another location or edit the tenancy start date"
@ -301,6 +301,9 @@ en:
reactivating_soon: reactivating_soon:
startdate: "The scheme %{name} is not available until %{date}. Enter a tenancy start date after %{date}" startdate: "The scheme %{name} is not available until %{date}. Enter a tenancy start date after %{date}"
scheme_id: "The scheme %{name} is not available until %{date}. Select another scheme or edit the tenancy start date" scheme_id: "The scheme %{name} is not available until %{date}. Select another scheme or edit the tenancy start date"
locations_inactive:
startdate: "The scheme %{name} has no locations that are active on this date. Enter another date or choose another scheme."
scheme_id: "The scheme %{name} has no locations that are active on this date. Enter another date or choose another scheme."
owning_organisation: owning_organisation:
invalid: "Please select the owning organisation or managing organisation that you belong to" invalid: "Please select the owning organisation or managing organisation that you belong to"
data_sharing_agreement_not_signed: "The organisation must accept the Data Sharing Agreement before it can be selected as the owning organisation." data_sharing_agreement_not_signed: "The organisation must accept the Data Sharing Agreement before it can be selected as the owning organisation."

79
spec/models/validations/setup_validations_spec.rb

@ -512,6 +512,60 @@ RSpec.describe Validations::SetupValidations do
end end
end end
context "with a scheme with no locations active on the start date & no location set" do
let(:scheme) { create(:scheme) }
let(:location) { create(:location, scheme:) }
before do
location_deactivation_period = build(:location_deactivation_period, deactivation_date: Time.zone.local(2022, 6, 4), location:)
location_deactivation_period.save!(validate: false)
location.reload
end
it "produces error when scheme does not have any active locations on the tenancy start date" do
record.startdate = Time.zone.local(2022, 7, 5)
record.scheme = scheme
setup_validator.validate_scheme(record)
expect(record.errors["startdate"]).to include(match I18n.t("validations.setup.startdate.scheme.locations_inactive.startdate", name: scheme.service_name))
expect(record.errors["scheme_id"]).to include(match I18n.t("validations.setup.startdate.scheme.locations_inactive.startdate", name: scheme.service_name))
end
it "produces no error when scheme has active locations on the tenancy start date" do
record.startdate = Time.zone.local(2022, 6, 1)
record.scheme = scheme
setup_validator.validate_scheme(record)
expect(record.errors["startdate"]).to be_empty
end
end
context "with a scheme with no locations active on the start date & location also set" do
let(:scheme) { create(:scheme) }
let(:location) { create(:location, scheme:) }
before do
location_deactivation_period = build(:location_deactivation_period, deactivation_date: Time.zone.local(2022, 6, 4), location:)
location_deactivation_period.save!(validate: false)
location.reload
end
it "produces error when scheme does not have any active locations on the tenancy start date" do
record.startdate = Time.zone.local(2022, 7, 5)
record.scheme = scheme
record.location = location
setup_validator.validate_scheme(record)
expect(record.errors["startdate"]).to include(match I18n.t("validations.setup.startdate.scheme.locations_inactive.startdate", name: scheme.service_name))
expect(record.errors["startdate"]).not_to include(match I18n.t("validations.setup.startdate.location.deactivated.startdate", postcode: location.postcode))
end
it "produces no error when scheme has active locations on the tenancy start date" do
record.startdate = Time.zone.local(2022, 6, 1)
record.scheme = scheme
record.location = location
setup_validator.validate_scheme(record)
expect(record.errors["startdate"]).to be_empty
end
end
context "with an incomplete scheme" do context "with an incomplete scheme" do
let(:scheme) { create(:scheme, :incomplete) } let(:scheme) { create(:scheme, :incomplete) }
@ -657,6 +711,31 @@ RSpec.describe Validations::SetupValidations do
expect(record.errors["location_id"]).to be_empty expect(record.errors["location_id"]).to be_empty
end end
end end
context "with the chosen location inactive on the tenancy start date" do
let(:scheme) { create(:scheme) }
let(:location) { create(:location, scheme:) }
before do
location_deactivation_period = build(:location_deactivation_period, deactivation_date: Time.zone.local(2022, 6, 4), location:)
location_deactivation_period.save!(validate: false)
location.reload
end
it "produces the location error when the chosen location is inactive on the tenancy start date" do
record.startdate = Time.zone.local(2022, 7, 5)
record.location = location
setup_validator.validate_location(record)
expect(record.errors["startdate"]).to include(match I18n.t("validations.setup.startdate.location.deactivated.startdate", postcode: location.postcode))
end
it "produces no error when the chosen location is active on the tenancy start date" do
record.startdate = Time.zone.local(2022, 6, 1)
record.location = location
setup_validator.validate_location(record)
expect(record.errors["startdate"]).to be_empty
end
end
end end
describe "#validate_organisation" do describe "#validate_organisation" do

Loading…
Cancel
Save