diff --git a/app/controllers/schemes_controller.rb b/app/controllers/schemes_controller.rb
index 208394942..21fb3a040 100644
--- a/app/controllers/schemes_controller.rb
+++ b/app/controllers/schemes_controller.rb
@@ -22,14 +22,16 @@ class SchemesController < ApplicationController
end
def new_deactivation
- if params[:scheme].blank?
+ @scheme_deactivation_period = SchemeDeactivationPeriod.new
+
+ if params[:scheme_deactivation_period].blank?
render "toggle_active", locals: { action: "deactivate" }
else
- @scheme.run_deactivation_validations = true
- @scheme.deactivation_date = deactivation_date
- @scheme.deactivation_date_type = params[:scheme][:deactivation_date_type]
- if @scheme.valid?
- redirect_to scheme_deactivate_confirm_path(@scheme, deactivation_date: @scheme.deactivation_date, deactivation_date_type: @scheme.deactivation_date_type)
+ @scheme_deactivation_period.deactivation_date = deactivation_date
+ @scheme_deactivation_period.deactivation_date_type = params[:scheme_deactivation_period][:deactivation_date_type]
+ @scheme_deactivation_period.scheme = @scheme
+ if @scheme_deactivation_period.validate
+ redirect_to scheme_deactivate_confirm_path(@scheme, deactivation_date: @scheme_deactivation_period.deactivation_date, deactivation_date_type: @scheme_deactivation_period.deactivation_date_type)
else
render "toggle_active", locals: { action: "deactivate" }, status: :unprocessable_entity
end
@@ -42,9 +44,7 @@ class SchemesController < ApplicationController
end
def deactivate
- @scheme.run_deactivation_validations!
-
- if @scheme.scheme_deactivation_periods.create!(deactivation_date:) && update_affected_logs
+ if SchemeDeactivationPeriod.create!(scheme_id: @scheme.id, deactivation_date: params[:deactivation_date]) && update_affected_logs
flash[:notice] = deactivate_success_notice
end
redirect_to scheme_details_path(@scheme)
@@ -299,28 +299,28 @@ private
when :deactivated
"#{@scheme.service_name} has been deactivated"
when :deactivating_soon
- "#{@scheme.service_name} will deactivate on #{deactivation_date.to_time.to_formatted_s(:govuk_date)}"
+ "#{@scheme.service_name} will deactivate on #{params[:deactivation_date].to_time.to_formatted_s(:govuk_date)}"
end
end
def deactivation_date
- if params[:scheme].blank?
+ if params[:scheme_deactivation_period].blank?
return
- elsif params[:scheme][:deactivation_date_type] == "default"
+ elsif params[:scheme_deactivation_period][:deactivation_date_type] == "default"
return FormHandler.instance.current_collection_start_date
- elsif params[:scheme][:deactivation_date].present?
- return params[:scheme][:deactivation_date]
+ elsif params[:scheme_deactivation_period][:deactivation_date].present?
+ return params[:scheme_deactivation_period][:deactivation_date]
end
- day = params[:scheme]["deactivation_date(3i)"]
- month = params[:scheme]["deactivation_date(2i)"]
- year = params[:scheme]["deactivation_date(1i)"]
+ day = params[:scheme_deactivation_period]["deactivation_date(3i)"]
+ month = params[:scheme_deactivation_period]["deactivation_date(2i)"]
+ year = params[:scheme_deactivation_period]["deactivation_date(1i)"]
return nil if [day, month, year].any?(&:blank?)
Time.zone.local(year.to_i, month.to_i, day.to_i) if Date.valid_date?(year.to_i, month.to_i, day.to_i)
end
def update_affected_logs
- @scheme.lettings_logs.filter_by_before_startdate(deactivation_date.to_time).update!(location: nil, scheme: nil)
+ @scheme.lettings_logs.filter_by_before_startdate(params[:deactivation_date].to_time).update!(location: nil, scheme: nil)
end
end
diff --git a/app/models/scheme.rb b/app/models/scheme.rb
index 3dfe1ff55..8197a147c 100644
--- a/app/models/scheme.rb
+++ b/app/models/scheme.rb
@@ -19,12 +19,9 @@ class Scheme < ApplicationRecord
}
validate :validate_confirmed
- validate :deactivation_date_errors
auto_strip_attributes :service_name
- attr_accessor :deactivation_date_type, :deactivation_date, :run_deactivation_validations
-
SENSITIVE = {
No: 0,
Yes: 1,
@@ -227,29 +224,4 @@ class Scheme < ApplicationRecord
def active?
status == :active
end
-
- def run_deactivation_validations!
- @run_deactivation_validations = true
- end
-
- def implicit_run_deactivation_validations
- deactivation_date.present? || @run_deactivation_validations
- end
-
- def deactivation_date_errors
- return unless implicit_run_deactivation_validations
-
- if deactivation_date.blank?
- if deactivation_date_type.blank?
- errors.add(:deactivation_date_type, message: I18n.t("validations.scheme.deactivation_date.not_selected"))
- elsif deactivation_date_type == "other"
- errors.add(:deactivation_date, message: I18n.t("validations.scheme.deactivation_date.invalid"))
- end
- else
- collection_start_date = FormHandler.instance.current_collection_start_date
- unless deactivation_date.between?(collection_start_date, Time.zone.local(2200, 1, 1))
- errors.add(:deactivation_date, message: I18n.t("validations.scheme.deactivation_date.out_of_range", date: collection_start_date.to_formatted_s(:govuk_date)))
- end
- end
- end
end
diff --git a/app/models/scheme_deactivation_period.rb b/app/models/scheme_deactivation_period.rb
index 5caba5c7a..f83a68e62 100644
--- a/app/models/scheme_deactivation_period.rb
+++ b/app/models/scheme_deactivation_period.rb
@@ -1,3 +1,24 @@
+class SchemeDeactivationPeriodValidator < ActiveModel::Validator
+ def validate(record)
+ if record.deactivation_date.blank?
+ if record.deactivation_date_type.blank?
+ record.errors.add(:deactivation_date_type, message: I18n.t("validations.scheme.deactivation_date.not_selected"))
+ elsif record.deactivation_date_type == "other"
+ record.errors.add(:deactivation_date, message: I18n.t("validations.scheme.deactivation_date.invalid"))
+ end
+ else
+ collection_start_date = FormHandler.instance.current_collection_start_date
+ unless record.deactivation_date.between?(collection_start_date, Time.zone.local(2200, 1, 1))
+ record.errors.add(:deactivation_date, message: I18n.t("validations.scheme.deactivation_date.out_of_range", date: collection_start_date.to_formatted_s(:govuk_date)))
+ end
+ end
+ end
+end
+
class SchemeDeactivationPeriod < ApplicationRecord
+ validates_with SchemeDeactivationPeriodValidator
+ belongs_to :scheme
+ attr_accessor :deactivation_date_type, :reactivation_date_type
+
scope :deactivations_without_reactivation, -> { where(reactivation_date: nil) }
end
diff --git a/app/views/schemes/deactivate_confirm.html.erb b/app/views/schemes/deactivate_confirm.html.erb
index 45f7d4341..0cfd454c8 100644
--- a/app/views/schemes/deactivate_confirm.html.erb
+++ b/app/views/schemes/deactivate_confirm.html.erb
@@ -1,6 +1,6 @@
<% title = "Deactivate #{@scheme.service_name}" %>
<% content_for :title, title %>
-<%= form_with model: @scheme, url: scheme_deactivate_path(@scheme), method: "patch", local: true do |f| %>
+<%= form_with model: @scheme_deactivation_period, url: scheme_deactivate_path(@scheme), method: "patch", local: true do |f| %>
<% content_for :before_content do %>
<%= govuk_back_link(href: :back) %>
<% end %>
diff --git a/app/views/schemes/toggle_active.html.erb b/app/views/schemes/toggle_active.html.erb
index 11dd2f276..fbb3ebc5f 100644
--- a/app/views/schemes/toggle_active.html.erb
+++ b/app/views/schemes/toggle_active.html.erb
@@ -6,7 +6,7 @@
href: scheme_details_path(@scheme),
) %>
<% end %>
-<%= form_with model: @scheme, url: scheme_new_deactivation_path(@scheme), method: "patch", local: true do |f| %>
+<%= form_with model: @scheme_deactivation_period, url: scheme_new_deactivation_path(@scheme), method: "patch", local: true do |f| %>
<% collection_start_date = FormHandler.instance.current_collection_start_date %>
diff --git a/spec/helpers/schemes_helper_spec.rb b/spec/helpers/schemes_helper_spec.rb
index 1924a6cc5..9db3639d9 100644
--- a/spec/helpers/schemes_helper_spec.rb
+++ b/spec/helpers/schemes_helper_spec.rb
@@ -35,8 +35,9 @@ RSpec.describe SchemesHelper do
context "with previous deactivations" do
before do
- scheme.scheme_deactivation_periods << FactoryBot.create(:scheme_deactivation_period, deactivation_date: Time.zone.local(2022, 8, 10), reactivation_date: Time.zone.local(2022, 9, 1))
- scheme.scheme_deactivation_periods << FactoryBot.create(:scheme_deactivation_period, deactivation_date: Time.zone.local(2022, 9, 15), reactivation_date: nil)
+ FactoryBot.create(:scheme_deactivation_period, deactivation_date: Time.zone.local(2022, 8, 10), reactivation_date: Time.zone.local(2022, 9, 1), scheme:)
+ FactoryBot.create(:scheme_deactivation_period, deactivation_date: Time.zone.local(2022, 9, 15), reactivation_date: nil, scheme:)
+ scheme.reload
end
it "displays the timeline of availability" do
diff --git a/spec/models/scheme_spec.rb b/spec/models/scheme_spec.rb
index d95d867dc..b19e8c992 100644
--- a/spec/models/scheme_spec.rb
+++ b/spec/models/scheme_spec.rb
@@ -109,27 +109,27 @@ RSpec.describe Scheme, type: :model do
end
it "returns deactivating soon if deactivation_date is in the future" do
- scheme.scheme_deactivation_periods << FactoryBot.create(:scheme_deactivation_period, deactivation_date: Time.zone.local(2022, 8, 8))
- scheme.save!
+ FactoryBot.create(:scheme_deactivation_period, deactivation_date: Time.zone.local(2022, 8, 8), scheme:)
+ scheme.reload
expect(scheme.status).to eq(:deactivating_soon)
end
it "returns deactivated if deactivation_date is in the past" do
- scheme.scheme_deactivation_periods << FactoryBot.create(:scheme_deactivation_period, deactivation_date: Time.zone.local(2022, 6, 6))
- scheme.save!
+ FactoryBot.create(:scheme_deactivation_period, deactivation_date: Time.zone.local(2022, 6, 6), scheme:)
+ scheme.reload
expect(scheme.status).to eq(:deactivated)
end
it "returns deactivated if deactivation_date is today" do
- scheme.scheme_deactivation_periods << FactoryBot.create(:scheme_deactivation_period, deactivation_date: Time.zone.local(2022, 6, 7))
- scheme.save!
+ FactoryBot.create(:scheme_deactivation_period, deactivation_date: Time.zone.local(2022, 6, 7), scheme:)
+ scheme.reload
expect(scheme.status).to eq(:deactivated)
end
end
context "when there have been previous deactivations" do
before do
- scheme.scheme_deactivation_periods << FactoryBot.create(:scheme_deactivation_period, deactivation_date: Time.zone.local(2022, 6, 4), reactivation_date: Time.zone.local(2022, 6, 5))
+ FactoryBot.create(:scheme_deactivation_period, deactivation_date: Time.zone.local(2022, 6, 4), reactivation_date: Time.zone.local(2022, 6, 5), scheme:)
end
it "returns active if the scheme has no relevant deactivation records" do
@@ -137,30 +137,22 @@ RSpec.describe Scheme, type: :model do
end
it "returns deactivating soon if deactivation_date is in the future" do
- scheme.scheme_deactivation_periods << FactoryBot.create(:scheme_deactivation_period, deactivation_date: Time.zone.local(2022, 8, 8))
- scheme.save!
+ FactoryBot.create(:scheme_deactivation_period, deactivation_date: Time.zone.local(2022, 8, 8), scheme:)
+ scheme.reload
expect(scheme.status).to eq(:deactivating_soon)
end
it "returns deactivated if deactivation_date is in the past" do
- scheme.scheme_deactivation_periods << FactoryBot.create(:scheme_deactivation_period, deactivation_date: Time.zone.local(2022, 6, 6))
- scheme.save!
+ FactoryBot.create(:scheme_deactivation_period, deactivation_date: Time.zone.local(2022, 6, 6), scheme:)
+ scheme.reload
expect(scheme.status).to eq(:deactivated)
end
it "returns deactivated if deactivation_date is today" do
- scheme.scheme_deactivation_periods << FactoryBot.create(:scheme_deactivation_period, deactivation_date: Time.zone.local(2022, 6, 7))
- scheme.save!
+ FactoryBot.create(:scheme_deactivation_period, deactivation_date: Time.zone.local(2022, 6, 7), scheme:)
+ scheme.reload
expect(scheme.status).to eq(:deactivated)
end
end
end
-
- describe "with deactivation_date (but no deactivation_date_type)" do
- let(:scheme) { FactoryBot.create(:scheme, deactivation_date: Date.new(2022, 4, 1)) }
-
- it "is valid" do
- expect(scheme).to be_valid
- end
- end
end
diff --git a/spec/requests/schemes_controller_spec.rb b/spec/requests/schemes_controller_spec.rb
index 59d044050..0c3b47f1a 100644
--- a/spec/requests/schemes_controller_spec.rb
+++ b/spec/requests/schemes_controller_spec.rb
@@ -270,7 +270,7 @@ RSpec.describe SchemesController, type: :request do
end
context "with deactivated scheme" do
- let(:scheme_deactivation_period) { FactoryBot.create(:scheme_deactivation_period, deactivation_date: Time.zone.local(2022, 10, 9)) }
+ let(:scheme_deactivation_period) { FactoryBot.create(:scheme_deactivation_period, deactivation_date: Time.zone.local(2022, 10, 9), scheme:) }
it "renders reactivate this scheme" do
expect(response).to have_http_status(:ok)
@@ -279,7 +279,7 @@ RSpec.describe SchemesController, type: :request do
end
context "with scheme that's deactivating soon" do
- let(:scheme_deactivation_period) { FactoryBot.create(:scheme_deactivation_period, deactivation_date: Time.zone.local(2022, 10, 12)) }
+ let(:scheme_deactivation_period) { FactoryBot.create(:scheme_deactivation_period, deactivation_date: Time.zone.local(2022, 10, 12), scheme:) }
it "renders reactivate this scheme" do
expect(response).to have_http_status(:ok)
@@ -1785,7 +1785,7 @@ RSpec.describe SchemesController, type: :request do
end
context "with default date" do
- let(:params) { { scheme: { deactivation_date_type: "default", deactivation_date: } } }
+ let(:params) { { scheme_deactivation_period: { deactivation_date_type: "default", deactivation_date: } } }
it "redirects to the confirmation page" do
follow_redirect!
@@ -1795,7 +1795,7 @@ RSpec.describe SchemesController, type: :request do
end
context "with other date" do
- let(:params) { { scheme: { deactivation_date_type: "other", "deactivation_date(3i)": "10", "deactivation_date(2i)": "10", "deactivation_date(1i)": "2022" } } }
+ let(:params) { { scheme_deactivation_period: { deactivation_date_type: "other", "deactivation_date(3i)": "10", "deactivation_date(2i)": "10", "deactivation_date(1i)": "2022" } } }
it "redirects to the confirmation page" do
follow_redirect!
@@ -1805,7 +1805,7 @@ RSpec.describe SchemesController, type: :request do
end
context "when confirming deactivation" do
- let(:params) { { scheme: { deactivation_date:, confirm: true, deactivation_date_type: "other" } } }
+ let(:params) { { deactivation_date:, confirm: true, deactivation_date_type: "other" } }
before do
Timecop.freeze(Time.utc(2022, 10, 10))
@@ -1851,7 +1851,7 @@ RSpec.describe SchemesController, type: :request do
end
context "when the date is not selected" do
- let(:params) { { scheme: { "deactivation_date": "" } } }
+ let(:params) { { scheme_deactivation_period: { "deactivation_date": "" } } }
it "displays the new page with an error message" do
expect(response).to have_http_status(:unprocessable_entity)
@@ -1860,7 +1860,7 @@ RSpec.describe SchemesController, type: :request do
end
context "when invalid date is entered" do
- let(:params) { { scheme: { deactivation_date_type: "other", "deactivation_date(3i)": "10", "deactivation_date(2i)": "44", "deactivation_date(1i)": "2022" } } }
+ let(:params) { { scheme_deactivation_period: { deactivation_date_type: "other", "deactivation_date(3i)": "10", "deactivation_date(2i)": "44", "deactivation_date(1i)": "2022" } } }
it "displays the new page with an error message" do
expect(response).to have_http_status(:unprocessable_entity)
@@ -1869,7 +1869,7 @@ RSpec.describe SchemesController, type: :request do
end
context "when the date is entered is before the beginning of current collection window" do
- let(:params) { { scheme: { deactivation_date_type: "other", "deactivation_date(3i)": "10", "deactivation_date(2i)": "4", "deactivation_date(1i)": "2020" } } }
+ let(:params) { { scheme_deactivation_period: { deactivation_date_type: "other", "deactivation_date(3i)": "10", "deactivation_date(2i)": "4", "deactivation_date(1i)": "2020" } } }
it "displays the new page with an error message" do
expect(response).to have_http_status(:unprocessable_entity)
@@ -1878,7 +1878,7 @@ RSpec.describe SchemesController, type: :request do
end
context "when the day is not entered" do
- let(:params) { { scheme: { deactivation_date_type: "other", "deactivation_date(3i)": "", "deactivation_date(2i)": "2", "deactivation_date(1i)": "2022" } } }
+ let(:params) { { scheme_deactivation_period: { deactivation_date_type: "other", "deactivation_date(3i)": "", "deactivation_date(2i)": "2", "deactivation_date(1i)": "2022" } } }
it "displays page with an error message" do
expect(response).to have_http_status(:unprocessable_entity)
@@ -1887,7 +1887,7 @@ RSpec.describe SchemesController, type: :request do
end
context "when the month is not entered" do
- let(:params) { { scheme: { deactivation_date_type: "other", "deactivation_date(3i)": "2", "deactivation_date(2i)": "", "deactivation_date(1i)": "2022" } } }
+ let(:params) { { scheme_deactivation_period: { deactivation_date_type: "other", "deactivation_date(3i)": "2", "deactivation_date(2i)": "", "deactivation_date(1i)": "2022" } } }
it "displays page with an error message" do
expect(response).to have_http_status(:unprocessable_entity)
@@ -1896,7 +1896,7 @@ RSpec.describe SchemesController, type: :request do
end
context "when the year is not entered" do
- let(:params) { { scheme: { deactivation_date_type: "other", "deactivation_date(3i)": "2", "deactivation_date(2i)": "2", "deactivation_date(1i)": "" } } }
+ let(:params) { { scheme_deactivation_period: { deactivation_date_type: "other", "deactivation_date(3i)": "2", "deactivation_date(2i)": "2", "deactivation_date(1i)": "" } } }
it "displays page with an error message" do
expect(response).to have_http_status(:unprocessable_entity)