From 15d4c9a202d1160d3455bbe622cf1d450c40b823 Mon Sep 17 00:00:00 2001 From: Robert Sullivan Date: Thu, 29 Feb 2024 17:28:53 +0000 Subject: [PATCH] CLDC-1944: Replace soft date validation with hard date validation for 2024 and allow dates before 2000 in cases of soft validation failure --- app/controllers/form_controller.rb | 2 +- .../form/sales/pages/handover_date_check.rb | 2 +- .../form/sales/pages/sale_date_check.rb | 2 +- .../sales/sale_information_validations.rb | 11 +++- config/locales/en.yml | 8 +-- .../sales/pages/handover_date_check_spec.rb | 2 +- .../form/sales/pages/sale_date_check_spec.rb | 2 +- .../sale_information_validations_spec.rb | 54 +++++++++++++++---- 8 files changed, 62 insertions(+), 21 deletions(-) diff --git a/app/controllers/form_controller.rb b/app/controllers/form_controller.rb index 17fd9af77..18633e3e8 100644 --- a/app/controllers/form_controller.rb +++ b/app/controllers/form_controller.rb @@ -86,7 +86,7 @@ private year = params[@log.model_name.param_key]["#{question.id}(1i)"] next unless [day, month, year].any?(&:present?) - result[question.id] = if Date.valid_date?(year.to_i, month.to_i, day.to_i) && year.to_i.between?(2000, 2200) + result[question.id] = if Date.valid_date?(year.to_i, month.to_i, day.to_i) && year.to_i > 0 Date.new(year.to_i, month.to_i, day.to_i) else Date.new(0, 1, 1) diff --git a/app/models/form/sales/pages/handover_date_check.rb b/app/models/form/sales/pages/handover_date_check.rb index 2a3bfdbf3..735354480 100644 --- a/app/models/form/sales/pages/handover_date_check.rb +++ b/app/models/form/sales/pages/handover_date_check.rb @@ -6,7 +6,7 @@ class Form::Sales::Pages::HandoverDateCheck < ::Form::Page { "saledate_check" => 1, "hodate_3_years_or_more_saledate?" => true }] @informative_text = {} @title_text = { - "translation" => "validations.sale_information.hodate.must_be_less_than_3_years_from_saledate", + "translation" => "validations.sale_information.hodate.must_be_less_than_3_years_from_saledate_soft", "arguments" => [], } end diff --git a/app/models/form/sales/pages/sale_date_check.rb b/app/models/form/sales/pages/sale_date_check.rb index acb34589c..f77d7154f 100644 --- a/app/models/form/sales/pages/sale_date_check.rb +++ b/app/models/form/sales/pages/sale_date_check.rb @@ -6,7 +6,7 @@ class Form::Sales::Pages::SaleDateCheck < ::Form::Page { "hodate_check" => 1, "hodate_3_years_or_more_saledate?" => true }] @informative_text = {} @title_text = { - "translation" => "validations.sale_information.saledate.must_be_less_than_3_years_from_hodate", + "translation" => "validations.sale_information.saledate.must_be_less_than_3_years_from_hodate_soft", "arguments" => [], } end diff --git a/app/models/validations/sales/sale_information_validations.rb b/app/models/validations/sales/sale_information_validations.rb index 17f827367..46176b63a 100644 --- a/app/models/validations/sales/sale_information_validations.rb +++ b/app/models/validations/sales/sale_information_validations.rb @@ -1,14 +1,21 @@ module Validations::Sales::SaleInformationValidations + include Validations::SharedValidations include CollectionTimeHelper include MoneyFormattingHelper - def validate_practical_completion_date_before_saledate(record) - return if record.saledate.blank? || record.hodate.blank? + def validate_practical_completion_date(record) + return unless !record.hodate.blank? && date_valid?("hodate", record) + return if record.saledate.blank? if record.hodate > record.saledate record.errors.add :hodate, I18n.t("validations.sale_information.hodate.must_be_before_saledate") record.errors.add :saledate, I18n.t("validations.sale_information.saledate.must_be_after_hodate") end + + if record.saledate - record.hodate >= 3.years && record.form.start_year_after_2024? + record.errors.add :hodate, :over_a_year_from_saledate, message: I18n.t("validations.sale_information.hodate.must_be_less_than_3_years_from_saledate") + record.errors.add :saledate, I18n.t("validations.sale_information.saledate.must_be_less_than_3_years_from_hodate") + end end def validate_exchange_date(record) diff --git a/config/locales/en.yml b/config/locales/en.yml index 9746ba13f..4818f1d9b 100644 --- a/config/locales/en.yml +++ b/config/locales/en.yml @@ -605,14 +605,16 @@ en: rent_to_buy: "Rent to Buy buyers should not have lived here before" hodate: must_be_before_saledate: "Practical completion or handover date must be before sale completion date" - must_be_less_than_3_years_from_saledate: "You told us practical completion or handover date is more than 3 years before sale completion date" + must_be_less_than_3_years_from_saledate_soft: "You told us practical completion or handover date is more than 3 years before sale completion date" + must_be_less_than_3_years_from_saledate: "Practical completion or handover date must be less than 3 years before sale completion date" exdate: must_be_before_saledate: "Contract exchange date must be before sale completion date" must_be_less_than_1_year_from_saledate: "Contract exchange date must be less than 1 year before sale completion date" saledate: must_be_after_exdate: "Sale completion date must be after contract exchange date" must_be_less_than_1_year_from_exdate: "Sale completion date must be less than 1 year after contract exchange date" - must_be_less_than_3_years_from_hodate: "You told us sale completion date is more than 3 years after practical completion or handover date" + must_be_less_than_3_years_from_hodate: "Sale completion date must be less than 3 years after practical completion or handover date" + must_be_less_than_3_years_from_hodate_soft: "You told us sale completion date is more than 3 years after practical completion or handover date" must_be_after_hodate: "Sale completion date must be after practical completion or handover date" previous_property_type: property_type_bedsit: "A bedsit cannot have more than 1 bedroom" @@ -626,7 +628,7 @@ en: value: over_discounted_london_max: "The percentage discount multiplied by the purchase price is %{discount_value}. This figure should not be more than £136,400 for properties in London." over_discounted_max: "The percentage discount multiplied by the purchase price is %{discount_value}. This figure should not be more than £102,400 for properties outside of London." - non_staircasing_mortgage: + non_staircasing_mortgage: mortgage_used: "The mortgage and deposit added together is %{mortgage_and_deposit_total} and the purchase price times by the equity is %{expected_shared_ownership_deposit_value}. These figures should be the same." mortgage_not_used: "The deposit is %{deposit} and the purchase price times by the equity is %{expected_shared_ownership_deposit_value}. As no mortgage was used, these figures should be the same." staircasing_mortgage: diff --git a/spec/models/form/sales/pages/handover_date_check_spec.rb b/spec/models/form/sales/pages/handover_date_check_spec.rb index cd358a2b8..bc614ae7f 100644 --- a/spec/models/form/sales/pages/handover_date_check_spec.rb +++ b/spec/models/form/sales/pages/handover_date_check_spec.rb @@ -25,7 +25,7 @@ RSpec.describe Form::Sales::Pages::HandoverDateCheck, type: :model do it "has the correct title_text" do expect(page.title_text).to eq({ - "translation" => "validations.sale_information.hodate.must_be_less_than_3_years_from_saledate", + "translation" => "validations.sale_information.hodate.must_be_less_than_3_years_from_saledate_soft", "arguments" => [], }) end diff --git a/spec/models/form/sales/pages/sale_date_check_spec.rb b/spec/models/form/sales/pages/sale_date_check_spec.rb index f1e0b3e2b..85576cedc 100644 --- a/spec/models/form/sales/pages/sale_date_check_spec.rb +++ b/spec/models/form/sales/pages/sale_date_check_spec.rb @@ -25,7 +25,7 @@ RSpec.describe Form::Sales::Pages::SaleDateCheck, type: :model do it "has the correct title_text" do expect(page.title_text).to eq({ - "translation" => "validations.sale_information.saledate.must_be_less_than_3_years_from_hodate", + "translation" => "validations.sale_information.saledate.must_be_less_than_3_years_from_hodate_soft", "arguments" => [], }) end diff --git a/spec/models/validations/sales/sale_information_validations_spec.rb b/spec/models/validations/sales/sale_information_validations_spec.rb index 316f7b7d0..9ae84834c 100644 --- a/spec/models/validations/sales/sale_information_validations_spec.rb +++ b/spec/models/validations/sales/sale_information_validations_spec.rb @@ -5,12 +5,12 @@ RSpec.describe Validations::Sales::SaleInformationValidations do let(:validator_class) { Class.new { include Validations::Sales::SaleInformationValidations } } - describe "#validate_practical_completion_date_before_saledate" do + describe "#validate_practical_completion_date" do context "when hodate blank" do let(:record) { build(:sales_log, hodate: nil) } it "does not add an error" do - sale_information_validator.validate_practical_completion_date_before_saledate(record) + sale_information_validator.validate_practical_completion_date(record) expect(record.errors).not_to be_present end @@ -20,7 +20,7 @@ RSpec.describe Validations::Sales::SaleInformationValidations do let(:record) { build(:sales_log, saledate: nil) } it "does not add an error" do - sale_information_validator.validate_practical_completion_date_before_saledate(record) + sale_information_validator.validate_practical_completion_date(record) expect(record.errors).not_to be_present end @@ -30,27 +30,59 @@ RSpec.describe Validations::Sales::SaleInformationValidations do let(:record) { build(:sales_log, hodate: nil, saledate: nil) } it "does not add an error" do - sale_information_validator.validate_practical_completion_date_before_saledate(record) + sale_information_validator.validate_practical_completion_date(record) expect(record.errors).not_to be_present end end - context "when hodate before saledate" do - let(:record) { build(:sales_log, hodate: 2.months.ago, saledate: 1.month.ago) } + context "when hodate invalid" do + let(:record) { build(:sales_log, hodate: Date.new(0, 1, 1)) } - it "does not add the error" do - sale_information_validator.validate_practical_completion_date_before_saledate(record) + it "adds an error" do + sale_information_validator.validate_practical_completion_date(record) + + expect(record.errors[:hodate]).to be_present + end + end + + context "when hodate less than 3 years before saledate" do + let(:record) { build(:sales_log, hodate: Date.new(2021, 12, 2), saledate: Date.new(2024, 12, 1)) } + + it "does not add an error" do + sale_information_validator.validate_practical_completion_date(record) expect(record.errors).not_to be_present end end + context "when hodate 3 or more years before saledate" do + context "and form year is 2023 or earlier" do + let(:record) { build(:sales_log, hodate: Date.new(2020, 12, 1), saledate: Date.new(2023, 12, 1)) } + + it "does not add an error" do + sale_information_validator.validate_practical_completion_date(record) + + expect(record.errors).not_to be_present + end + end + + context "and form year is 2024 or later" do + let(:record) { build(:sales_log, hodate: Date.new(2021, 12, 1), saledate: Date.new(2024, 12, 1)) } + + it "adds an error" do + sale_information_validator.validate_practical_completion_date(record) + + expect(record.errors[:hodate]).to be_present + end + end + end + context "when hodate after saledate" do let(:record) { build(:sales_log, hodate: 1.month.ago, saledate: 2.months.ago) } - it "adds error" do - sale_information_validator.validate_practical_completion_date_before_saledate(record) + it "adds an error" do + sale_information_validator.validate_practical_completion_date(record) expect(record.errors[:hodate]).to be_present end @@ -60,7 +92,7 @@ RSpec.describe Validations::Sales::SaleInformationValidations do let(:record) { build(:sales_log, hodate: Time.zone.parse("2023-07-01"), saledate: Time.zone.parse("2023-07-01")) } it "does not add an error" do - sale_information_validator.validate_practical_completion_date_before_saledate(record) + sale_information_validator.validate_practical_completion_date(record) expect(record.errors[:hodate]).not_to be_present end