Browse Source

CLDC-1687 allow deactivation or reactivation of last year schemes and locations in crossover period (#1396)

* create method to test whether we are currently in the crossover period and associated tests

* update copy, use method for testing whether we are in the crossover period, remove focus from test file

* reuse existing method to determine whether we are in a collection period

* use the existing method and update validations

* fix test broken by changes

* update location in same way as scheme

* create method on FormHandler that finds the start date of the earliest collection period

* ensure that default deactivation and reactivation dates also reflect the changes

* create tests for the new validations

* lint correction

* minor copy change

* minor logic change

* amend naming error after rebase conflict
remove test that is no longer correct after change on another branch to functionality
update a test after a copy change
pull/1523/head
Arthur Campbell 2 years ago committed by GitHub
parent
commit
9bbc2c2e17
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
  1. 2
      app/controllers/locations_controller.rb
  2. 2
      app/controllers/schemes_controller.rb
  3. 4
      app/models/form_handler.rb
  4. 12
      app/models/location_deactivation_period.rb
  5. 10
      app/models/scheme_deactivation_period.rb
  6. 6
      app/views/locations/toggle_active.html.erb
  7. 6
      app/views/schemes/toggle_active.html.erb
  8. 6
      config/locales/en.yml
  9. 4
      spec/features/schemes_spec.rb
  10. 83
      spec/models/location_deactivation_period_spec.rb
  11. 68
      spec/models/scheme_deactivation_period_spec.rb

2
app/controllers/locations_controller.rb

@ -269,7 +269,7 @@ private
if params[:location_deactivation_period].blank?
return
elsif params[:location_deactivation_period]["#{key}_type".to_sym] == "default"
return FormHandler.instance.current_collection_start_date
return FormHandler.instance.start_date_of_earliest_open_collection_period
elsif params[:location_deactivation_period][key.to_sym].present?
return params[:location_deactivation_period][key.to_sym]
end

2
app/controllers/schemes_controller.rb

@ -296,7 +296,7 @@ private
if params[:scheme_deactivation_period].blank?
return
elsif params[:scheme_deactivation_period]["#{key}_type".to_sym] == "default"
return FormHandler.instance.current_collection_start_date
return FormHandler.instance.start_date_of_earliest_open_collection_period
elsif params[:scheme_deactivation_period][key.to_sym].present?
return params[:scheme_deactivation_period][key.to_sym]
end

4
app/models/form_handler.rb

@ -77,6 +77,10 @@ class FormHandler
form_mappings[current_collection_start_year - year]
end
def start_date_of_earliest_open_collection_period
in_crossover_period? ? previous_collection_start_date : current_collection_start_date
end
def in_crossover_period?(now: Time.zone.now)
lettings_in_crossover_period?(now:) || sales_in_crossover_period?(now:)
end

12
app/models/location_deactivation_period.rb

@ -1,4 +1,6 @@
class LocationDeactivationPeriodValidator < ActiveModel::Validator
include CollectionTimeHelper
def validate(record)
location = record.location
recent_deactivation = location.location_deactivation_periods.deactivations_without_reactivation.first
@ -16,7 +18,7 @@ class LocationDeactivationPeriodValidator < ActiveModel::Validator
elsif record.reactivation_date_type == "other"
record.errors.add(:reactivation_date, message: I18n.t("validations.location.toggle_date.invalid"))
end
elsif !record.reactivation_date.between?(location.available_from, Time.zone.local(2200, 1, 1))
elsif record.reactivation_date.before? location.available_from
record.errors.add(:reactivation_date, message: I18n.t("validations.location.toggle_date.out_of_range", date: location.available_from.to_formatted_s(:govuk_date)))
elsif record.reactivation_date < recent_deactivation.deactivation_date
record.errors.add(:reactivation_date, message: I18n.t("validations.location.reactivation.before_deactivation", date: recent_deactivation.deactivation_date.to_formatted_s(:govuk_date)))
@ -32,10 +34,10 @@ class LocationDeactivationPeriodValidator < ActiveModel::Validator
end
elsif location.location_deactivation_periods.any? { |period| period.reactivation_date.present? && record.deactivation_date.between?(period.deactivation_date, period.reactivation_date - 1.day) }
record.errors.add(:deactivation_date, message: I18n.t("validations.location.deactivation.during_deactivated_period"))
else
unless record.deactivation_date.between?(location.available_from, Time.zone.local(2200, 1, 1))
record.errors.add(:deactivation_date, message: I18n.t("validations.location.toggle_date.out_of_range", date: location.available_from.to_formatted_s(:govuk_date)))
end
elsif record.deactivation_date.before? FormHandler.instance.start_date_of_earliest_open_collection_period
record.errors.add(:deactivation_date, message: I18n.t("validations.location.toggle_date.out_of_range", date: FormHandler.instance.start_date_of_earliest_open_collection_period.to_formatted_s(:govuk_date)))
elsif record.deactivation_date.before? location.available_from
record.errors.add(:deactivation_date, message: I18n.t("validations.location.toggle_date.before_creation", date: location.available_from.to_formatted_s(:govuk_date)))
end
end
end

10
app/models/scheme_deactivation_period.rb

@ -1,4 +1,6 @@
class SchemeDeactivationPeriodValidator < ActiveModel::Validator
include CollectionTimeHelper
def validate(record)
scheme = record.scheme
recent_deactivation = scheme.scheme_deactivation_periods.deactivations_without_reactivation.first
@ -32,10 +34,10 @@ class SchemeDeactivationPeriodValidator < ActiveModel::Validator
end
elsif scheme.scheme_deactivation_periods.any? { |period| period.reactivation_date.present? && record.deactivation_date.between?(period.deactivation_date, period.reactivation_date - 1.day) }
record.errors.add(:deactivation_date, message: I18n.t("validations.scheme.deactivation.during_deactivated_period"))
else
unless record.deactivation_date.between?(scheme.available_from, Time.zone.local(2200, 1, 1))
record.errors.add(:deactivation_date, message: I18n.t("validations.scheme.toggle_date.out_of_range", date: scheme.available_from.to_formatted_s(:govuk_date)))
end
elsif record.deactivation_date.before? FormHandler.instance.start_date_of_earliest_open_collection_period
record.errors.add(:deactivation_date, message: I18n.t("validations.scheme.toggle_date.out_of_range", date: FormHandler.instance.start_date_of_earliest_open_collection_period.to_formatted_s(:govuk_date)))
elsif record.deactivation_date.before? scheme.available_from
record.errors.add(:deactivation_date, message: I18n.t("validations.scheme.toggle_date.before_creation", date: scheme.available_from.to_formatted_s(:govuk_date)))
end
end
end

6
app/views/locations/toggle_active.html.erb

@ -11,16 +11,16 @@
<%= form_with model: @location_deactivation_period, url: toggle_location_form_path(action, @location), method: "patch", local: true do |f| %>
<div class="govuk-grid-row">
<div class="govuk-grid-column-two-thirds">
<% collection_start_date = FormHandler.instance.earliest_open_collection_start_date(now: @location.available_from) %>
<% start_date = FormHandler.instance.earliest_open_collection_start_date(now: @location.available_from) %>
<%= f.govuk_error_summary %>
<%= f.govuk_radio_buttons_fieldset date_type_question(action),
legend: { text: I18n.t("questions.location.toggle_active.apply_from") },
caption: { text: title },
hint: { text: I18n.t("hints.location.toggle_active", date: collection_start_date.to_formatted_s(:govuk_date)) } do %>
hint: { text: I18n.t("hints.location.toggle_active", date: start_date.to_formatted_s(:govuk_date)) } do %>
<%= govuk_warning_text text: I18n.t("warnings.location.#{action}.existing_logs") %>
<%= f.govuk_radio_button date_type_question(action),
"default",
label: { text: "From the start of the current collection period (#{collection_start_date.to_formatted_s(:govuk_date)})" } %>
label: { text: "From the start of the open collection period (#{start_date.to_formatted_s(:govuk_date)})" } %>
<%= f.govuk_radio_button date_type_question(action),
"other",

6
app/views/schemes/toggle_active.html.erb

@ -11,16 +11,16 @@
<%= form_with model: @scheme_deactivation_period, url: toggle_scheme_form_path(action, @scheme), method: "patch", local: true do |f| %>
<div class="govuk-grid-row">
<div class="govuk-grid-column-two-thirds">
<% collection_start_date = FormHandler.instance.current_collection_start_date %>
<% start_date = FormHandler.instance.start_date_of_earliest_open_collection_period %>
<%= f.govuk_error_summary %>
<%= 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: collection_start_date.to_formatted_s(:govuk_date)) } do %>
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") %>
<%= f.govuk_radio_button date_type_question(action),
"default",
label: { text: "From the start of the current collection period (#{collection_start_date.to_formatted_s(:govuk_date)})" } %>
label: { text: "From the start of the open collection period (#{start_date.to_formatted_s(:govuk_date)})" } %>
<%= f.govuk_radio_button date_type_question(action),
"other",
label: { text: "For tenancies starting after a certain date" },

6
config/locales/en.yml

@ -456,6 +456,7 @@ en:
toggle_date:
not_selected: "Select one of the options"
invalid: "Enter a valid day, month and year"
before_creation: "The scheme cannot be deactivated before %{date}, the start of the collection year when it was created"
out_of_range: "The date must be on or after the %{date}"
reactivation:
before_deactivation: "This scheme was deactivated on %{date}. The reactivation date must be on or after deactivation date"
@ -474,6 +475,7 @@ en:
toggle_date:
not_selected: "Select one of the options"
invalid: "Enter a valid day, month and year"
before_creation: "The location cannot be deactivated before %{date}, the date when it was first available"
out_of_range: "The date must be on or after the %{date}"
reactivation:
before_deactivation: "This location was deactivated on %{date}. The reactivation date must be on or after deactivation date"
@ -594,10 +596,10 @@ en:
postcode: "For example, SW1P 4DF."
name: "This is how you refer to this location within your organisation"
units: "A unit is the space being let. For example, the property might be a block of flats and the unit would be the specific flat being let. A unit can also be a bedroom in a shared house or flat. Do not include spaces used for staff."
toggle_active: "If the date is before %{date}, select ‘From the start of the current collection period’ because the previous period has now closed."
toggle_active: "If the date is before %{date}, select ‘From the start of the open collection period’ because the previous period has now closed."
startdate: "For example, 27 3 2021"
scheme:
toggle_active: "If the date is before %{date}, select ‘From the start of the current collection period’ because the previous period has now closed."
toggle_active: "If the date is before %{date}, select ‘From the start of the open collection period’ because the previous period has now closed."
bulk_upload:
needstype: "General needs housing includes both self-contained and shared housing without support or specific adaptations. Supported housing can include direct access hostels, group homes, residential care and nursing homes."
offered: "Do not include the offer that led to this letting. This is after the last tenancy ended. If the property is being offered for let for the first time, enter 0."

4
spec/features/schemes_spec.rb

@ -742,7 +742,7 @@ RSpec.describe "Schemes scheme Features" do
expect(page).to have_current_path("/schemes/#{scheme.id}/locations")
end
context "when location is incative" do
context "when location is inactive" do
context "and I click to view the location" do
before do
click_link(deactivated_location.postcode)
@ -766,7 +766,7 @@ RSpec.describe "Schemes scheme Features" do
expect(page).to have_current_path("/schemes/#{scheme.id}/locations/#{deactivated_location.id}/new-reactivation")
expect(page).to have_content("Reactivate #{deactivated_location.name}")
expect(page).to have_content("You’ll be able to add logs with this location if their tenancy start date is on or after the date you enter.")
expect(page).to have_content("If the date is before 1 April 2022, select ‘From the start of the current collection period’ because the previous period has now closed.")
expect(page).to have_content("If the date is before 1 April 2022, select ‘From the start of the open collection period’ because the previous period has now closed.")
end
context "when I press the back button" do

83
spec/models/location_deactivation_period_spec.rb

@ -0,0 +1,83 @@
require "rails_helper"
RSpec.describe LocationDeactivationPeriod do
let(:validator) { LocationDeactivationPeriodValidator.new }
let(:location) { FactoryBot.create(:location, startdate: now - 2.years) }
let(:record) { FactoryBot.create(:location_deactivation_period, deactivation_date: now, location:) }
describe "#validate" do
around do |example|
Timecop.freeze(now) do
example.run
end
end
context "when not in a crossover period" do
let(:now) { Time.utc(2023, 3, 1) }
context "with a deactivation date before the current collection period" do
it "adds an error" do
record.deactivation_date = now - 1.year
location.location_deactivation_periods.clear
validator.validate(record)
expect(record.errors[:deactivation_date]).to include "The date must be on or after the 1 April 2022"
end
end
context "with a deactivation date in the current collection period" do
it "does not add an error" do
record.deactivation_date = now - 1.day
location.location_deactivation_periods.clear
validator.validate(record)
expect(record.errors).to be_empty
end
end
end
context "when in a crossover period" do
let(:now) { Time.utc(2023, 5, 1) }
context "with a deactivation date before the previous collection period" do
it "does not add an error" do
record.deactivation_date = now - 2.years
location.location_deactivation_periods.clear
validator.validate(record)
expect(record.errors[:deactivation_date]).to include "The date must be on or after the 1 April 2022"
end
end
context "with a deactivation date in the previous collection period" do
it "does not add an error" do
record.deactivation_date = now - 1.year
location.location_deactivation_periods.clear
validator.validate(record)
expect(record.errors).to be_empty
end
end
context "with a deactivation date in the current collection period" do
it "does not add an error" do
record.deactivation_date = now - 1.day
location.location_deactivation_periods.clear
validator.validate(record)
expect(record.errors).to be_empty
end
end
context "but the location was created in the current collection period" do
let(:location) { FactoryBot.create(:location, startdate:) }
let(:startdate) { now - 2.days }
context "with a deactivation date in the previous collection period" do
it "adds an error" do
record.deactivation_date = now - 1.year
location.location_deactivation_periods.clear
validator.validate(record)
start_date = startdate.to_formatted_s(:govuk_date)
expect(record.errors[:deactivation_date]).to include "The location cannot be deactivated before #{start_date}, the date when it was first available"
end
end
end
end
end
end

68
spec/models/scheme_deactivation_period_spec.rb

@ -0,0 +1,68 @@
require "rails_helper"
RSpec.describe SchemeDeactivationPeriod do
let(:validator) { SchemeDeactivationPeriodValidator.new }
let(:scheme) { FactoryBot.create(:scheme, created_at: now - 2.years) }
let(:record) { FactoryBot.create(:scheme_deactivation_period, deactivation_date: now, scheme:) }
describe "#validate" do
around do |example|
Timecop.freeze(now) do
example.run
end
end
context "when not in a crossover period" do
let(:now) { Time.utc(2023, 3, 1) }
context "with a deactivation date before the current collection period" do
it "adds an error" do
record.deactivation_date = now - 1.year
scheme.scheme_deactivation_periods.clear
validator.validate(record)
expect(record.errors[:deactivation_date]).to include("The date must be on or after the 1 April 2022")
end
end
context "with a deactivation date in the current collection period" do
it "does not add an error" do
record.deactivation_date = now - 1.day
scheme.scheme_deactivation_periods.clear
validator.validate(record)
expect(record.errors[:deactivation_date]).to be_empty
end
end
end
context "when in a crossover period" do
let(:now) { Time.utc(2023, 5, 1) }
context "with a deactivation date before the previous collection period" do
it "does not add an error" do
record.deactivation_date = now - 2.years
scheme.scheme_deactivation_periods.clear
validator.validate(record)
expect(record.errors[:deactivation_date]).to include("The date must be on or after the 1 April 2022")
end
end
context "with a deactivation date in the previous collection period" do
it "does not add an error" do
record.deactivation_date = now - 1.year
scheme.scheme_deactivation_periods.clear
validator.validate(record)
expect(record.errors[:deactivation_date]).to be_empty
end
end
context "with a deactivation date in the current collection period" do
it "does not add an error" do
record.deactivation_date = now - 1.day
scheme.scheme_deactivation_periods.clear
validator.validate(record)
expect(record.errors[:deactivation_date]).to be_empty
end
end
end
end
end
Loading…
Cancel
Save