Browse Source

Update scheme deactivation confirmation with affected locations

pull/2605/head
Manny Dinssa 2 years ago
parent
commit
74526e9faf
  1. 47
      app/controllers/schemes_controller.rb
  2. 10
      app/helpers/locations_helper.rb
  3. 11
      app/helpers/schemes_helper.rb
  4. 41
      app/models/location.rb
  5. 8
      app/models/scheme.rb
  6. 13
      app/views/locations/index.html.erb
  7. 47
      app/views/schemes/deactivate_confirm.html.erb
  8. 46
      spec/views/schemes/deactivate_confirm.html.erb_spec.rb

47
app/controllers/schemes_controller.rb

@ -51,17 +51,34 @@ 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
locations_active_on_deactivation_date, remaining_locations = scheme_locations.partition do |location|
location.status_at(@deactivation_date) == :active
end
locations_deactivating_after_deactivation_date, remaining_locations = remaining_locations.partition do |location|
location.status_at(@deactivation_date) == :deactivating_soon || location.status_at(@deactivation_date) == :reactivating_soon
end
locations_startdate_after_deactivation_date, = remaining_locations.partition do |location|
location.status_at(@deactivation_date) == :activating_soon
end
@affected_locations = locations_active_on_deactivation_date + locations_deactivating_after_deactivation_date + locations_startdate_after_deactivation_date
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
@ -370,4 +387,22 @@ private
def session_filters
filter_manager.session_filters
end
def deactivate_locations(deactivation_date)
# Add a deactivation period to @locations_without_deactivation_period
@locations_without_deactivation_period.each do |location|
LocationDeactivationPeriod.create!(location:, deactivation_date:)
end
# Change the deactivation period for @locations_with_future_deactivation_period
@locations_with_future_deactivation_period.each do |location|
location_deactivation_period = location.location_deactivation_periods.find_by("deactivation_date > ?", Time.zone.now)
location_deactivation_period.update!(deactivation_date:) if location_deactivation_period
end
# Clear the start date for @locations_with_future_start_date
@locations_with_future_start_date.each do |location|
location.update!(startdate: nil)
end
end
end

10
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)
@ -107,6 +107,14 @@ private
periods << ActivePeriod.new(deactivation.reactivation_date, nil)
end
if location.deactivated_by_scheme? || location.deactivating_soon_by_scheme?
scheme_periods = location.scheme.scheme_deactivation_periods.sort_by(&:deactivation_date)
scheme_periods.each do |scheme_period|
periods.last.to = scheme_period.deactivation_date
periods << ActivePeriod.new(scheme_period.reactivation_date, nil)
end
end
remove_overlapping_and_empty_periods(periods)
end

11
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)

41
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
@ -55,12 +56,17 @@ class Location < ApplicationRecord
scope :deactivated, lambda {
deactivated_by_organisation
.or(deactivated_directly)
.or(deactivated_by_scheme)
}
scope :deactivated_by_organisation, lambda {
merge(Organisation.filter_by_inactive)
}
scope :deactivated_by_scheme, lambda {
merge(Scheme.deactivated)
}
scope :deactivated_directly, lambda { |date = Time.zone.now|
merge(LocationDeactivationPeriod.deactivations_without_reactivation)
.where("location_deactivation_periods.deactivation_date <= ?", date)
@ -68,8 +74,13 @@ class Location < ApplicationRecord
scope :deactivating_soon, 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)
.where.not(id: joins(scheme: [:owning_organisation]).deactivated_by_organisation.pluck(:id))
.or(deactivating_soon_by_scheme)
}
scope :deactivating_soon_by_scheme, lambda {
merge(Scheme.deactivating_soon)
}
scope :reactivating_soon, lambda { |date = Time.zone.now|
@ -84,17 +95,19 @@ 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(:location_deactivation_periods).deactivated_directly.pluck(:id))
.where.not(id: joins(scheme: %i[owning_organisation scheme_deactivation_periods]).deactivated_by_scheme.pluck(:id))
.where.not(id: joins(scheme: [:scheme_deactivation_periods]).deactivating_soon_by_scheme.pluck(:id))
.where.not(id: joins(:location_deactivation_periods).deactivating_soon.pluck(:id))
.where.not(id: incomplete.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: joins(scheme: %i[owning_organisation scheme_deactivation_periods]).deactivated_by_scheme.pluck(:id))
.where.not(id: joins(scheme: [:scheme_deactivation_periods]).deactivating_soon_by_scheme.pluck(:id))
.where.not(id: incomplete.pluck(:id))
.where.not(id: activating_soon(date).pluck(:id))
}
@ -163,9 +176,9 @@ 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
:active
@ -187,6 +200,14 @@ 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 validate_postcode
if !postcode&.match(POSTCODE_REGEXP)
error_message = I18n.t("validations.postcode")

8
app/models/scheme.rb

@ -275,6 +275,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 +317,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

13
app/views/locations/index.html.erb

@ -56,10 +56,17 @@
<% end %>
<% end %>
<% if status_hint_message = scheme_status_hint(@scheme) %>
<div class="govuk-hint">
<%= status_hint_message %>
</div>
<br>
<% 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 %>
<br>
<%== render partial: "pagy/nav", locals: { pagy: @pagy, item_name: "locations" } %>
</div>
</div>
<%== render partial: "pagy/nav", locals: { pagy: @pagy, item_name: "locations" } %>

47
app/views/schemes/deactivate_confirm.html.erb

@ -2,16 +2,41 @@
<% content_for :before_content do %>
<%= govuk_back_link(href: :back) %>
<% end %>
<h1 class="govuk-heading-l">
<span class="govuk-caption-l"><%= @scheme.service_name %></span>
This change will affect <%= @affected_logs.count %> logs
</h1>
<%= 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 %>
<div class="govuk-button-group">
<%= f.govuk_submit "Deactivate this scheme" %>
<%= govuk_button_link_to "Cancel", scheme_details_path(@scheme), html: { method: :get }, secondary: true %>
<div class="govuk-grid-row">
<div class="govuk-grid-column-two-thirds">
<h1 class="govuk-heading-l">
<span class="govuk-caption-l"><%= @scheme.service_name %></span>
<% sentence_parts = [] %>
<% if @affected_logs.count > 0 %>
<% sentence_parts << pluralize(@affected_logs.count, 'log') %>
<% end %>
<% if @affected_locations.count > 0 %>
<% sentence_parts << pluralize(@affected_locations.count, 'location') %>
<% end %>
This change will affect <%= sentence_parts.join(' and ') %>.
</h1>
<% if @affected_logs.count > 0 %>
<p>
<%= 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) %>.
</p>
<% end %>
<%= govuk_warning_text text: I18n.t("warnings.scheme.deactivate.review_logs"), html_attributes: { class: "" } %>
<p>
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.
</p>
<br>
<%= f.hidden_field :confirm, value: true %>
<%= f.hidden_field :deactivation_date, value: @deactivation_date %>
<%= f.hidden_field :deactivation_date_type, value: @deactivation_date_type %>
<div class="govuk-button-group">
<%= f.govuk_submit "Deactivate this scheme" %>
<%= govuk_button_link_to "Cancel", scheme_details_path(@scheme), html: { method: :get }, secondary: true %>
</div>
</div>
</div>
<% end %>

46
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
Loading…
Cancel
Save