From 27188ad3a2d4bf5512ac530faefff152c7171297 Mon Sep 17 00:00:00 2001 From: Manny Dinssa <44172848+Dinssa@users.noreply.github.com> Date: Tue, 10 Sep 2024 09:20:08 +0100 Subject: [PATCH] CLDC-3001 Handle locations and logs on deactivate schemes (#2605) --- app/controllers/schemes_controller.rb | 19 +++-- app/helpers/deactivate_confirm_helper.rb | 8 +++ app/helpers/locations_helper.rb | 31 ++++++-- app/helpers/schemes_helper.rb | 11 ++- app/models/location.rb | 70 ++++++++++++++----- app/models/scheme.rb | 38 +++++++--- app/models/scheme_deactivation_period.rb | 1 + app/models/validations/shared_validations.rb | 6 +- app/views/locations/index.html.erb | 13 +++- app/views/schemes/deactivate_confirm.html.erb | 41 ++++++++--- app/views/schemes/toggle_active.html.erb | 13 ++-- spec/fixtures/files/locations_csv_export.csv | 2 +- .../schemes_and_locations_csv_export.csv | 2 +- spec/models/location_spec.rb | 33 +++++++++ spec/requests/schemes_controller_spec.rb | 31 +++++--- .../deactivate_confirm.html.erb_spec.rb | 46 ++++++++++++ 16 files changed, 293 insertions(+), 72 deletions(-) create mode 100644 app/helpers/deactivate_confirm_helper.rb create mode 100644 spec/views/schemes/deactivate_confirm.html.erb_spec.rb diff --git a/app/controllers/schemes_controller.rb b/app/controllers/schemes_controller.rb index c0a36b920..1468bc013 100644 --- a/app/controllers/schemes_controller.rb +++ b/app/controllers/schemes_controller.rb @@ -51,17 +51,24 @@ class SchemesController < ApplicationController end def deactivate_confirm - @affected_logs = @scheme.lettings_logs.visible.after_date(params[:deactivation_date]) - if @affected_logs.count.zero? + @deactivation_date = Time.zone.parse(params[:deactivation_date]) + @affected_logs = @scheme.lettings_logs.visible.after_date(@deactivation_date) + @deactivation_date_type = params[:deactivation_date_type] + + scheme_locations = @scheme.locations.confirmed + + @affected_locations = scheme_locations.select do |location| + %i[active deactivating_soon reactivating_soon activating_soon].include?(location.status_at(@deactivation_date)) + end + + if @affected_logs.count.zero? && @affected_locations.count.zero? deactivate - else - @deactivation_date = params[:deactivation_date] - @deactivation_date_type = params[:deactivation_date_type] end end def deactivate - if @scheme.open_deactivation&.update!(deactivation_date: params[:deactivation_date]) || @scheme.scheme_deactivation_periods.create!(deactivation_date: params[:deactivation_date]) + deactivation_date = params[:deactivation_date] + if @scheme.open_deactivation&.update!(deactivation_date:) || @scheme.scheme_deactivation_periods.create!(deactivation_date:) logs = reset_location_and_scheme_for_logs! flash[:notice] = deactivate_success_notice diff --git a/app/helpers/deactivate_confirm_helper.rb b/app/helpers/deactivate_confirm_helper.rb new file mode 100644 index 000000000..a7e9edb19 --- /dev/null +++ b/app/helpers/deactivate_confirm_helper.rb @@ -0,0 +1,8 @@ +module DeactivateConfirmHelper + def affected_title(affected_logs, affected_locations) + title_parts = [] + title_parts << pluralize(affected_logs.count, "log") if affected_logs.count.positive? + title_parts << pluralize(affected_locations.count, "location") if affected_locations.count.positive? + "This change will affect #{title_parts.join(' and ')}." + end +end diff --git a/app/helpers/locations_helper.rb b/app/helpers/locations_helper.rb index f963c7040..fc1008926 100644 --- a/app/helpers/locations_helper.rb +++ b/app/helpers/locations_helper.rb @@ -70,7 +70,7 @@ module LocationsHelper def toggle_location_link(location) return govuk_button_link_to "Deactivate this location", scheme_location_new_deactivation_path(location.scheme, location), warning: true if location.active? || location.deactivates_in_a_long_time? - return govuk_button_link_to "Reactivate this location", scheme_location_new_reactivation_path(location.scheme, location) if location.deactivated? + return govuk_button_link_to "Reactivate this location", scheme_location_new_reactivation_path(location.scheme, location) if location.deactivated? && !location.deactivated_by_scheme? end def delete_location_link(location) @@ -100,14 +100,37 @@ private ActivePeriod = Struct.new(:from, :to) def location_active_periods(location) periods = [ActivePeriod.new(location.available_from, nil)] + location_deactivation_periods = location_deactivation_periods(location) + scheme_deactivation_periods = scheme_deactivation_periods(location, location_deactivation_periods) - sorted_deactivation_periods = remove_nested_periods(location.location_deactivation_periods.sort_by(&:deactivation_date)) + combined_deactivation_periods = location_deactivation_periods + scheme_deactivation_periods + sorted_deactivation_periods = combined_deactivation_periods.sort_by(&:deactivation_date) + + update_periods_with_deactivations(periods, sorted_deactivation_periods) + remove_overlapping_and_empty_periods(periods) + end + + def location_deactivation_periods(location) + periods = remove_nested_periods(location.location_deactivation_periods.sort_by(&:deactivation_date)) + periods.last&.deactivation_date if periods.last&.reactivation_date.nil? + periods + end + + def scheme_deactivation_periods(location, location_deactivation_periods) + return [] unless location.scheme.scheme_deactivation_periods.any? + + location_deactivation_date = location_deactivation_periods.last&.deactivation_date + periods = remove_nested_periods(location.scheme.scheme_deactivation_periods.sort_by(&:deactivation_date)) + periods.select do |period| + period.deactivation_date >= location.available_from && (location_deactivation_date.nil? || period.deactivation_date <= location_deactivation_date) + end + end + + def update_periods_with_deactivations(periods, sorted_deactivation_periods) sorted_deactivation_periods.each do |deactivation| periods.last.to = deactivation.deactivation_date periods << ActivePeriod.new(deactivation.reactivation_date, nil) end - - remove_overlapping_and_empty_periods(periods) end def remove_overlapping_and_empty_periods(periods) diff --git a/app/helpers/schemes_helper.rb b/app/helpers/schemes_helper.rb index f96f9e4c8..0e318d283 100644 --- a/app/helpers/schemes_helper.rb +++ b/app/helpers/schemes_helper.rb @@ -12,7 +12,7 @@ module SchemesHelper def toggle_scheme_link(scheme) return govuk_button_link_to "Deactivate this scheme", scheme_new_deactivation_path(scheme), warning: true if scheme.active? || scheme.deactivates_in_a_long_time? - return govuk_button_link_to "Reactivate this scheme", scheme_new_reactivation_path(scheme) if scheme.deactivated? + return govuk_button_link_to "Reactivate this scheme", scheme_new_reactivation_path(scheme) if scheme.deactivated? || scheme.deactivating_soon? end def delete_scheme_link(scheme) @@ -76,6 +76,15 @@ module SchemesHelper end end + def scheme_status_hint(scheme) + case scheme.status + when :deactivating_soon + "This scheme deactivates on #{scheme.last_deactivation_date.to_formatted_s(:govuk_date)}. Any locations you add will be deactivated on the same date. Reactivate the scheme to add locations active after this date." + when :deactivated + "This scheme deactivated on #{scheme.last_deactivation_date.to_formatted_s(:govuk_date)}. Any locations you add will be deactivated on the same date. Reactivate the scheme to add locations active after this date." + end + end + private ActivePeriod = Struct.new(:from, :to) diff --git a/app/models/location.rb b/app/models/location.rb index 8efa4ee28..19cf5e211 100644 --- a/app/models/location.rb +++ b/app/models/location.rb @@ -40,6 +40,7 @@ class Location < ApplicationRecord filtered_records = filtered_records .left_outer_joins(:location_deactivation_periods) .joins(scheme: [:owning_organisation]) + .left_outer_joins(scheme: :scheme_deactivation_periods) .order("location_deactivation_periods.created_at DESC") .merge(scopes.reduce(&:or)) end @@ -52,30 +53,47 @@ class Location < ApplicationRecord .or(where(confirmed: nil)) } - scope :deactivated, lambda { + scope :deactivated, lambda { |date = Time.zone.now| deactivated_by_organisation - .or(deactivated_directly) + .or(deactivated_directly(date)) + .or(deactivated_by_scheme(date)) } scope :deactivated_by_organisation, lambda { merge(Organisation.filter_by_inactive) } + scope :deactivated_by_scheme, lambda { |date = Time.zone.now| + merge(Scheme.deactivated_directly(date)) + } + scope :deactivated_directly, lambda { |date = Time.zone.now| merge(LocationDeactivationPeriod.deactivations_without_reactivation) .where("location_deactivation_periods.deactivation_date <= ?", date) } - scope :deactivating_soon, lambda { |date = Time.zone.now| + scope :deactivating_soon_directly, lambda { |date = Time.zone.now| merge(LocationDeactivationPeriod.deactivations_without_reactivation) - .where("location_deactivation_periods.deactivation_date > ?", date) - .where.not(id: joins(scheme: [:owning_organisation]).deactivated_by_organisation.pluck(:id)) + .where("location_deactivation_periods.deactivation_date > ?", date) + } + + scope :deactivating_soon, lambda { |date = Time.zone.now| + deactivating_soon_directly + .or(deactivating_soon_by_scheme(date)) + } + + scope :deactivating_soon_by_scheme, lambda { |date = Time.zone.now| + merge(Scheme.deactivating_soon(date)) } scope :reactivating_soon, lambda { |date = Time.zone.now| where.not("location_deactivation_periods.reactivation_date IS NULL") - .where("location_deactivation_periods.reactivation_date > ?", date) - .where.not(id: joins(scheme: [:owning_organisation]).deactivated_by_organisation.pluck(:id)) + .where("location_deactivation_periods.reactivation_date > ?", date) + .where.not(id: joins(scheme: [:owning_organisation]).deactivated_by_organisation.pluck(:id)) + } + + scope :reactivating_soon_by_scheme, lambda { |date = Time.zone.now| + merge(Scheme.reactivating_soon(date)) } scope :activating_soon, lambda { |date = Time.zone.now| @@ -84,19 +102,21 @@ class Location < ApplicationRecord scope :active_status, lambda { where.not(id: joins(:location_deactivation_periods).reactivating_soon.pluck(:id)) - .where.not(id: joins(scheme: [:owning_organisation]).deactivated_by_organisation.pluck(:id)) - .where.not(id: joins(:location_deactivation_periods).deactivated_directly.pluck(:id)) - .where.not(id: incomplete.pluck(:id)) - .where.not(id: joins(:location_deactivation_periods).deactivating_soon.pluck(:id)) - .where.not(id: activating_soon.pluck(:id)) + .where.not(id: joins(scheme: [:scheme_deactivation_periods]).reactivating_soon_by_scheme.pluck(:id)) + .where.not(id: joins(:location_deactivation_periods).merge(Location.deactivated_directly).pluck(:id)) + .where.not(id: joins(scheme: [:scheme_deactivation_periods]).merge(Location.deactivated_by_scheme).pluck(:id)) + .where.not(id: joins(scheme: [:owning_organisation]).merge(Location.deactivated_by_organisation).pluck(:id)) + .where.not(id: incomplete.pluck(:id)) + .where.not(id: joins(:location_deactivation_periods).merge(Location.deactivating_soon_directly).pluck(:id)) + .where.not(id: joins(scheme: %i[owning_organisation scheme_deactivation_periods]).merge(Location.deactivating_soon_by_scheme).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: joins(:location_deactivation_periods).merge(Location.deactivated_directly(date)).pluck(:id)) + .where.not(id: incomplete.pluck(:id)) .where.not(id: activating_soon(date).pluck(:id)) + .where(scheme: Scheme.active(date)) } scope :visible, -> { where(discarded_at: nil) } @@ -163,10 +183,10 @@ class Location < ApplicationRecord return :deleted if discarded_at.present? return :incomplete unless confirmed 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 || scheme.status_at(date) == :deactivated + return :deactivating_soon if open_deactivation&.deactivation_date.present? && date < open_deactivation.deactivation_date || scheme.status_at(date) == :deactivating_soon return :activating_soon if startdate.present? && date < startdate - 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 || scheme.status_at(date) == :reactivating_soon :active end @@ -187,6 +207,18 @@ class Location < ApplicationRecord status_at(6.months.from_now) == :deactivating_soon end + def deactivated_by_scheme? + status == :deactivated && scheme.status == :deactivated + end + + def deactivating_soon_by_scheme? + status == :deactivating_soon && scheme.status == :deactivating_soon + end + + def reactivating_soon_by_scheme? + status == :reactivating_soon && scheme.status == :reactivating_soon + end + def validate_postcode if !postcode&.match(POSTCODE_REGEXP) error_message = I18n.t("validations.postcode") diff --git a/app/models/scheme.rb b/app/models/scheme.rb index 07ec14731..6d3524723 100644 --- a/app/models/scheme.rb +++ b/app/models/scheme.rb @@ -61,25 +61,27 @@ class Scheme < ApplicationRecord merge(Organisation.filter_by_inactive) } - scope :deactivated_directly, lambda { + scope :deactivated_directly, lambda { |date = Time.zone.now| merge(SchemeDeactivationPeriod.deactivations_without_reactivation) - .where("scheme_deactivation_periods.deactivation_date <= ?", Time.zone.now) + .where("scheme_deactivation_periods.deactivation_date <= ?", date) } - scope :deactivating_soon, lambda { + scope :deactivating_soon, lambda { |date = Time.zone.now| merge(SchemeDeactivationPeriod.deactivations_without_reactivation) - .where("scheme_deactivation_periods.deactivation_date > ? AND scheme_deactivation_periods.deactivation_date < ? ", Time.zone.now, 6.months.from_now) + .where("scheme_deactivation_periods.deactivation_date > ? AND scheme_deactivation_periods.deactivation_date < ? ", date, 6.months.from_now) .where.not(id: joins(:owning_organisation).deactivated_by_organisation.pluck(:id)) } - scope :reactivating_soon, lambda { - where.not("scheme_deactivation_periods.reactivation_date IS NULL") - .where("scheme_deactivation_periods.reactivation_date > ?", Time.zone.now) - .where.not(id: joins(:owning_organisation).deactivated_by_organisation.pluck(:id)) + scope :reactivating_soon, lambda { |date = Time.zone.now| + merge(SchemeDeactivationPeriod.deactivations_with_reactivation) + .where.not("scheme_deactivation_periods.reactivation_date IS NULL") + .where("scheme_deactivation_periods.reactivation_date > ?", date) + .where("scheme_deactivation_periods.deactivation_date <= ?", date) + .where.not(id: joins(:owning_organisation).deactivated_by_organisation.pluck(:id)) } - scope :activating_soon, lambda { - where("schemes.startdate > ?", Time.zone.now) + scope :activating_soon, lambda { |date = Time.zone.now| + where("schemes.startdate > ?", date) } scope :active_status, lambda { @@ -91,6 +93,14 @@ class Scheme < ApplicationRecord .where.not(id: activating_soon.pluck(:id)) } + scope :active, lambda { |date = Time.zone.now| + where.not(id: joins(:scheme_deactivation_periods).reactivating_soon(date).pluck(:id)) + .where.not(id: incomplete.pluck(:id)) + .where.not(id: joins(:owning_organisation).deactivated_by_organisation.pluck(:id)) + .where.not(id: joins(:owning_organisation).joins(:scheme_deactivation_periods).deactivated_directly(date).pluck(:id)) + .where.not(id: activating_soon(date).pluck(:id)) + } + scope :visible, -> { where(discarded_at: nil) } validate :validate_confirmed @@ -275,6 +285,10 @@ class Scheme < ApplicationRecord scheme_deactivation_periods.where("deactivation_date <= ?", date).order("created_at").last end + def last_deactivation_date + scheme_deactivation_periods.order(deactivation_date: :desc).first&.deactivation_date + end + def status @status ||= status_at(Time.zone.now) end @@ -313,6 +327,10 @@ class Scheme < ApplicationRecord status == :deactivated end + def deactivating_soon? + status == :deactivating_soon + end + def deactivates_in_a_long_time? status_at(6.months.from_now) == :deactivating_soon end diff --git a/app/models/scheme_deactivation_period.rb b/app/models/scheme_deactivation_period.rb index 176d15211..cb27534f7 100644 --- a/app/models/scheme_deactivation_period.rb +++ b/app/models/scheme_deactivation_period.rb @@ -48,4 +48,5 @@ class SchemeDeactivationPeriod < ApplicationRecord attr_accessor :deactivation_date_type, :reactivation_date_type scope :deactivations_without_reactivation, -> { where(reactivation_date: nil) } + scope :deactivations_with_reactivation, -> { where.not(reactivation_date: nil) } end diff --git a/app/models/validations/shared_validations.rb b/app/models/validations/shared_validations.rb index ab9f9d7a8..217b2c170 100644 --- a/app/models/validations/shared_validations.rb +++ b/app/models/validations/shared_validations.rb @@ -102,7 +102,11 @@ module Validations::SharedValidations return unless %i[reactivating_soon activating_soon deactivated].include?(status) closest_reactivation = resource.last_deactivation_before(date) - open_deactivation = resource.open_deactivation + open_deactivation = if resource.is_a?(Location) + resource.open_deactivation || resource.scheme.open_deactivation + else + resource.open_deactivation + end date = case status when :reactivating_soon then closest_reactivation.reactivation_date diff --git a/app/views/locations/index.html.erb b/app/views/locations/index.html.erb index 78a362332..64d9bf286 100644 --- a/app/views/locations/index.html.erb +++ b/app/views/locations/index.html.erb @@ -56,10 +56,17 @@ <% end %> <% end %> + <% if status_hint_message = scheme_status_hint(@scheme) %> +
+ <%= status_hint_message %> +
+
+ <% end %> + <% if LocationPolicy.new(current_user, @scheme.locations.new).create? %> - <%= govuk_button_to "Add a location", scheme_locations_path(@scheme), method: "post", secondary: true %> + <%= govuk_button_to "Add a location", scheme_locations_path(@scheme), method: "post" %> <% end %> +
+ <%== render partial: "pagy/nav", locals: { pagy: @pagy, item_name: "locations" } %> - -<%== render partial: "pagy/nav", locals: { pagy: @pagy, item_name: "locations" } %> diff --git a/app/views/schemes/deactivate_confirm.html.erb b/app/views/schemes/deactivate_confirm.html.erb index b5dda160e..a73208e75 100644 --- a/app/views/schemes/deactivate_confirm.html.erb +++ b/app/views/schemes/deactivate_confirm.html.erb @@ -2,16 +2,35 @@ <% content_for :before_content do %> <%= govuk_back_link(href: :back) %> <% end %> -

- <%= @scheme.service_name %> - This change will affect <%= @affected_logs.count %> logs -

- <%= govuk_warning_text text: I18n.t("warnings.scheme.deactivate.review_logs") %> - <%= f.hidden_field :confirm, value: true %> - <%= f.hidden_field :deactivation_date, value: @deactivation_date %> - <%= f.hidden_field :deactivation_date_type, value: @deactivation_date_type %> -
- <%= f.govuk_submit "Deactivate this scheme" %> - <%= govuk_button_link_to "Cancel", scheme_details_path(@scheme), html: { method: :get }, secondary: true %> +
+
+ +

+ <%= @scheme.service_name %> + <%= affected_title(@affected_logs, @affected_locations) %> +

+ + <% if @affected_logs.count > 0 %> +

+ <%= pluralize(@affected_logs.count, "existing log") %> using this scheme <%= @affected_logs.count == 1 ? "has" : "have" %> a tenancy start date after <%= @deactivation_date.to_formatted_s(:govuk_date) %>. +

+ <%= govuk_warning_text text: I18n.t("warnings.scheme.deactivate.review_logs"), html_attributes: { class: "" } %> + <% end %> + + <% if @affected_locations.count > 0 %> +

+ This scheme has <%= pluralize(@affected_locations.count, "location") %> active on <%= @deactivation_date.to_formatted_s(:govuk_date) %>. <%= @affected_locations.count == 1 ? "This location" : "These locations" %> will deactivate on that date. If the scheme is ever reactivated, <%= @affected_locations.count == 1 ? "this location" : "these locations" %> will reactivate as well. +

+
+ <% end %> + + <%= f.hidden_field :confirm, value: true %> + <%= f.hidden_field :deactivation_date, value: @deactivation_date %> + <%= f.hidden_field :deactivation_date_type, value: @deactivation_date_type %> +
+ <%= f.govuk_submit "Deactivate this scheme" %> + <%= govuk_button_link_to "Cancel", scheme_details_path(@scheme), html: { method: :get }, secondary: true %> +
+
<% end %> diff --git a/app/views/schemes/toggle_active.html.erb b/app/views/schemes/toggle_active.html.erb index b23c9591c..3e2f1d4a8 100644 --- a/app/views/schemes/toggle_active.html.erb +++ b/app/views/schemes/toggle_active.html.erb @@ -3,7 +3,7 @@ <% content_for :before_content do %> <%= govuk_back_link( - href: scheme_details_path(@scheme), + href: scheme_path(@scheme), ) %> <% end %> @@ -12,11 +12,12 @@
<% start_date = FormHandler.instance.earliest_open_for_editing_collection_start_date %> <%= f.govuk_error_summary %> + <%= title %> +

<%= I18n.t("questions.scheme.toggle_active.apply_from") %>

+ <%= govuk_warning_text text: I18n.t("warnings.scheme.#{action}.existing_logs") %> +

<%= I18n.t("hints.scheme.toggle_active", date: start_date.to_formatted_s(:govuk_date)) %>

<%= f.govuk_radio_buttons_fieldset date_type_question(action), - legend: { text: I18n.t("questions.scheme.toggle_active.apply_from") }, - caption: { text: title }, - hint: { text: I18n.t("hints.scheme.toggle_active", date: start_date.to_formatted_s(:govuk_date)) } do %> - <%= govuk_warning_text text: I18n.t("warnings.scheme.#{action}.existing_logs") %> + legend: { text: I18n.t("questions.scheme.toggle_active.apply_from"), hidden: true } do %> <%= f.govuk_radio_button date_type_question(action), "default", label: { text: "From the start of the open collection period (#{start_date.to_formatted_s(:govuk_date)})" } %> @@ -26,7 +27,7 @@ **basic_conditional_html_attributes({ "deactivation_date" => %w[other] }, "scheme") do %> <%= f.govuk_date_field date_question(action), legend: { text: "Date", size: "m" }, - hint: { text: "For example, 27 3 2022" }, + hint: { text: "For example, 27 3 2025" }, width: 20 %> <% end %> <% end %> diff --git a/spec/fixtures/files/locations_csv_export.csv b/spec/fixtures/files/locations_csv_export.csv index 51844b6c5..5b80ae024 100644 --- a/spec/fixtures/files/locations_csv_export.csv +++ b/spec/fixtures/files/locations_csv_export.csv @@ -1,2 +1,2 @@ scheme_code,location_code,location_postcode,location_name,location_status,location_local_authority,location_units,location_type_of_unit,location_mobility_type,location_active_dates -,,SW1A 2AA,Downing Street,deactivating_soon,Westminster,20,Self-contained house,Fitted with equipment and adaptations,"Active from 1 April 2022 to 25 December 2023, Deactivated on 26 December 2023" +,,SW1A 2AA,Downing Street,deactivating_soon,Westminster,20,Self-contained house,Fitted with equipment and adaptations,"Active from 1 April 2023 to 25 December 2023, Deactivated on 26 December 2023" diff --git a/spec/fixtures/files/schemes_and_locations_csv_export.csv b/spec/fixtures/files/schemes_and_locations_csv_export.csv index 79c9132f6..d662dceb3 100644 --- a/spec/fixtures/files/schemes_and_locations_csv_export.csv +++ b/spec/fixtures/files/schemes_and_locations_csv_export.csv @@ -1,2 +1,2 @@ scheme_code,scheme_service_name,scheme_status,scheme_confidential,scheme_type,scheme_registered_under_care_act,scheme_owning_organisation_name,scheme_support_services_provided_by,scheme_primary_client_group,scheme_has_other_client_group,scheme_secondary_client_group,scheme_support_type,scheme_intended_stay,scheme_created_at,scheme_active_dates,location_code,location_postcode,location_name,location_status,location_local_authority,location_units,location_type_of_unit,location_mobility_type,location_active_dates -,Test name,active,Yes,Housing for older people,No,MHCLG,The same organisation that owns the housing stock,People with alcohol problems,Yes,Older people with support needs,High level,Medium stay,2021-04-01T00:00:00+01:00,"Active from 1 April 2020 to 31 March 2022, Deactivated on 1 April 2022, Active from 1 April 2023",,SW1A 2AA,Downing Street,deactivating_soon,Westminster,20,Self-contained house,Fitted with equipment and adaptations,"Active from 1 April 2022 to 25 December 2023, Deactivated on 26 December 2023" +,Test name,active,Yes,Housing for older people,No,MHCLG,The same organisation that owns the housing stock,People with alcohol problems,Yes,Older people with support needs,High level,Medium stay,2021-04-01T00:00:00+01:00,"Active from 1 April 2020 to 31 March 2022, Deactivated on 1 April 2022, Active from 1 April 2023",,SW1A 2AA,Downing Street,deactivating_soon,Westminster,20,Self-contained house,Fitted with equipment and adaptations,"Active from 1 April 2023 to 25 December 2023, Deactivated on 26 December 2023" diff --git a/spec/models/location_spec.rb b/spec/models/location_spec.rb index 2f991ab31..4856c5662 100644 --- a/spec/models/location_spec.rb +++ b/spec/models/location_spec.rb @@ -930,6 +930,39 @@ RSpec.describe Location, type: :model do expect(location.status).to eq(:activating_soon) end end + + context "when the scheme the location belongs to is deactivated" do + before do + FactoryBot.create(:scheme_deactivation_period, deactivation_date: Time.zone.yesterday, scheme: location.scheme) + location.save! + end + + it "returns deactivated" do + expect(location.status).to eq(:deactivated) + end + end + + context "when the scheme the location belongs to is deactivating soon" do + before do + FactoryBot.create(:scheme_deactivation_period, deactivation_date: Time.zone.today + 1.month, scheme: location.scheme) + location.save! + end + + it "returns deactivating soon" do + expect(location.status).to eq(:deactivating_soon) + end + end + + context "when the scheme the location belongs to is reactivating soon" do + before do + FactoryBot.create(:scheme_deactivation_period, deactivation_date: Time.zone.yesterday, reactivation_date: Time.zone.tomorrow, scheme: location.scheme) + location.save! + end + + it "returns reactivating soon" do + expect(location.status).to eq(:reactivating_soon) + end + end end describe "status_at" do diff --git a/spec/requests/schemes_controller_spec.rb b/spec/requests/schemes_controller_spec.rb index 579cfd1a9..d93bc873d 100644 --- a/spec/requests/schemes_controller_spec.rb +++ b/spec/requests/schemes_controller_spec.rb @@ -612,9 +612,9 @@ RSpec.describe SchemesController, type: :request do context "with scheme that's deactivating soon" do let(:scheme_deactivation_period) { create(:scheme_deactivation_period, deactivation_date: Time.zone.local(2022, 10, 12), scheme:) } - it "does not render toggle scheme link" do + it "does render the reactivate this scheme button" do expect(response).to have_http_status(:ok) - expect(page).not_to have_link("Reactivate this scheme") + expect(page).to have_link("Reactivate this scheme") expect(page).not_to have_link("Deactivate this scheme") end end @@ -680,9 +680,9 @@ RSpec.describe SchemesController, type: :request do context "with scheme that's deactivating soon" do let(:scheme_deactivation_period) { create(:scheme_deactivation_period, deactivation_date: Time.zone.local(2022, 10, 12), scheme: specific_scheme) } - it "does not render toggle scheme link" do + it "does render the reactivate this scheme button" do expect(response).to have_http_status(:ok) - expect(page).not_to have_link("Reactivate this scheme") + expect(page).to have_link("Reactivate this scheme") expect(page).not_to have_link("Deactivate this scheme") end end @@ -784,6 +784,7 @@ RSpec.describe SchemesController, type: :request do context "and associated logs in editable collection period" do before do + create(:location, scheme:) create(:lettings_log, :sh, scheme:, startdate: Time.zone.local(2022, 9, 9), owning_organisation: user.organisation) get "/schemes/#{scheme.id}" end @@ -2533,14 +2534,18 @@ RSpec.describe SchemesController, type: :request do it "redirects to the confirmation page" do follow_redirect! expect(response).to have_http_status(:ok) - expect(page).to have_content("This change will affect #{scheme.lettings_logs.count} logs") + expect(page).to have_content("This change will affect #{scheme.lettings_logs.count} log and 1 location.") end end context "and no affected logs" do let(:setup_schemes) { scheme.lettings_logs.update(scheme: nil) } - it "redirects to the location page and updates the deactivation period" do + before do + create(:location_deactivation_period, deactivation_date: Time.zone.local(2022, 4, 1), reactivation_date: nil, location:) + end + + it "redirects to the scheme page and updates the deactivation period" do follow_redirect! follow_redirect! follow_redirect! @@ -2560,14 +2565,18 @@ RSpec.describe SchemesController, type: :request do it "redirects to the confirmation page" do follow_redirect! expect(response).to have_http_status(:ok) - expect(page).to have_content("This change will affect #{scheme.lettings_logs.count} logs") + expect(page).to have_content("This change will affect #{scheme.lettings_logs.count} log and 1 location.") end end context "and no affected logs" do let(:setup_schemes) { scheme.lettings_logs.update(scheme: nil) } - it "redirects to the location page and updates the deactivation period" do + before do + create(:location_deactivation_period, deactivation_date: Time.zone.local(2022, 4, 5), reactivation_date: nil, location:) + end + + it "redirects to the scheme page and updates the deactivation period" do follow_redirect! follow_redirect! follow_redirect! @@ -2751,6 +2760,10 @@ RSpec.describe SchemesController, type: :request do let(:params) { { scheme_deactivation_period: { deactivation_date_type: "other", "deactivation_date(3i)": "8", "deactivation_date(2i)": "9", "deactivation_date(1i)": "2023" } } } let(:add_deactivations) { create(:scheme_deactivation_period, deactivation_date: Time.zone.local(2023, 6, 5), reactivation_date: nil, scheme:) } + before do + create(:location_deactivation_period, deactivation_date: Time.zone.local(2022, 4, 5), reactivation_date: nil, location:) + end + it "redirects to the scheme page and updates the existing deactivation period" do follow_redirect! follow_redirect! @@ -2771,7 +2784,7 @@ RSpec.describe SchemesController, type: :request do it "redirects to the confirmation page" do follow_redirect! expect(response).to have_http_status(:ok) - expect(page).to have_content("This change will affect 1 logs") + expect(page).to have_content("This change will affect 1 log and 1 location.") end end end diff --git a/spec/views/schemes/deactivate_confirm.html.erb_spec.rb b/spec/views/schemes/deactivate_confirm.html.erb_spec.rb new file mode 100644 index 000000000..fd1f2a2ac --- /dev/null +++ b/spec/views/schemes/deactivate_confirm.html.erb_spec.rb @@ -0,0 +1,46 @@ +require "rails_helper" + +RSpec.describe "schemes/deactivate_confirm.html.erb", type: :view do + let(:scheme) { create(:scheme, service_name: "ABCScheme") } + let(:deactivation_date) { Time.zone.today + 1.month } + let(:affected_logs) { create_list(:lettings_log, 2, scheme:, status: 1) } + let(:affected_locations) { create_list(:location, 3, scheme:) } + let(:scheme_deactivation_period) { SchemeDeactivationPeriod.new } + + before do + assign(:scheme, scheme) + assign(:deactivation_date, deactivation_date) + assign(:affected_logs, affected_logs) + assign(:affected_locations, affected_locations) + assign(:scheme_deactivation_period, scheme_deactivation_period) + render + end + + it "displays the service name in the caption" do + expect(rendered).to have_css("span.govuk-caption-l", text: scheme.service_name) + end + + it "displays the correct heading" do + expect(rendered).to have_css("h1.govuk-heading-l", text: "This change will affect 2 logs and 3 locations.") + end + + it "displays the affected logs count" do + expect(rendered).to have_text("2 existing logs using this scheme have a tenancy start date after #{deactivation_date.to_formatted_s(:govuk_date)}.") + end + + it "displays the warning text" do + expect(rendered).to have_css(".govuk-warning-text", text: I18n.t("warnings.scheme.deactivate.review_logs")) + end + + it "displays the affected locations count" do + expect(rendered).to have_text("This scheme has 3 locations active on #{deactivation_date.to_formatted_s(:govuk_date)}.") + end + + it "renders the submit button" do + expect(rendered).to have_button("Deactivate this scheme") + end + + it "renders the cancel button" do + expect(rendered).to have_link("Cancel", href: scheme_details_path(scheme)) + end +end