From 5d7649a9e46b844a516d4c479f807b7edcce3a74 Mon Sep 17 00:00:00 2001 From: kosiakkatrina <54268893+kosiakkatrina@users.noreply.github.com> Date: Fri, 10 Jan 2025 12:35:04 +0000 Subject: [PATCH 1/7] CLDC-3821 Remove care home questions (#2885) * Remove carehome questions for 2025 * Update routing to rent pages for 2025 * lint --- .../form/lettings/pages/rent_4_weekly.rb | 19 +++- .../form/lettings/pages/rent_bi_weekly.rb | 19 +++- .../form/lettings/pages/rent_monthly.rb | 19 +++- app/models/form/lettings/pages/rent_weekly.rb | 19 +++- .../subsections/income_and_benefits.rb | 22 +++-- .../form/lettings/pages/rent4_weekly_spec.rb | 44 +++++++++ .../lettings/pages/rent_bi_weekly_spec.rb | 44 +++++++++ .../form/lettings/pages/rent_monthly_spec.rb | 44 +++++++++ .../form/lettings/pages/rent_weekly_spec.rb | 44 +++++++++ .../subsections/income_and_benefits_spec.rb | 93 +++++++++++++------ 10 files changed, 317 insertions(+), 50 deletions(-) create mode 100644 spec/models/form/lettings/pages/rent4_weekly_spec.rb create mode 100644 spec/models/form/lettings/pages/rent_bi_weekly_spec.rb create mode 100644 spec/models/form/lettings/pages/rent_monthly_spec.rb create mode 100644 spec/models/form/lettings/pages/rent_weekly_spec.rb diff --git a/app/models/form/lettings/pages/rent_4_weekly.rb b/app/models/form/lettings/pages/rent_4_weekly.rb index aa6441f6e..4bfaf28ff 100644 --- a/app/models/form/lettings/pages/rent_4_weekly.rb +++ b/app/models/form/lettings/pages/rent_4_weekly.rb @@ -3,10 +3,7 @@ class Form::Lettings::Pages::Rent4Weekly < ::Form::Page super @id = "rent_4_weekly" @copy_key = "lettings.income_and_benefits.rent_and_charges" - @depends_on = [ - { "household_charge" => 0, "rent_and_charges_paid_every_4_weeks?" => true, "is_carehome?" => false }, - { "household_charge" => nil, "rent_and_charges_paid_every_4_weeks?" => true, "is_carehome?" => false }, - ] + @depends_on = depends_on end def questions @@ -18,4 +15,18 @@ class Form::Lettings::Pages::Rent4Weekly < ::Form::Page Form::Lettings::Questions::Tcharge4Weekly.new(nil, nil, self), ] end + + def depends_on + if form.start_year_2025_or_later? + [ + { "household_charge" => 0, "rent_and_charges_paid_every_4_weeks?" => true }, + { "household_charge" => nil, "rent_and_charges_paid_every_4_weeks?" => true }, + ] + else + [ + { "household_charge" => 0, "rent_and_charges_paid_every_4_weeks?" => true, "is_carehome?" => false }, + { "household_charge" => nil, "rent_and_charges_paid_every_4_weeks?" => true, "is_carehome?" => false }, + ] + end + end end diff --git a/app/models/form/lettings/pages/rent_bi_weekly.rb b/app/models/form/lettings/pages/rent_bi_weekly.rb index 7eab8daf4..aad9e9312 100644 --- a/app/models/form/lettings/pages/rent_bi_weekly.rb +++ b/app/models/form/lettings/pages/rent_bi_weekly.rb @@ -3,10 +3,7 @@ class Form::Lettings::Pages::RentBiWeekly < ::Form::Page super @id = "rent_bi_weekly" @copy_key = "lettings.income_and_benefits.rent_and_charges" - @depends_on = [ - { "household_charge" => nil, "rent_and_charges_paid_every_2_weeks?" => true, "is_carehome?" => false }, - { "household_charge" => 0, "rent_and_charges_paid_every_2_weeks?" => true, "is_carehome?" => false }, - ] + @depends_on = depends_on end def questions @@ -18,4 +15,18 @@ class Form::Lettings::Pages::RentBiWeekly < ::Form::Page Form::Lettings::Questions::TchargeBiWeekly.new(nil, nil, self), ] end + + def depends_on + if form.start_year_2025_or_later? + [ + { "household_charge" => nil, "rent_and_charges_paid_every_2_weeks?" => true }, + { "household_charge" => 0, "rent_and_charges_paid_every_2_weeks?" => true }, + ] + else + [ + { "household_charge" => nil, "rent_and_charges_paid_every_2_weeks?" => true, "is_carehome?" => false }, + { "household_charge" => 0, "rent_and_charges_paid_every_2_weeks?" => true, "is_carehome?" => false }, + ] + end + end end diff --git a/app/models/form/lettings/pages/rent_monthly.rb b/app/models/form/lettings/pages/rent_monthly.rb index 9a3cd6a7e..1fcc21b17 100644 --- a/app/models/form/lettings/pages/rent_monthly.rb +++ b/app/models/form/lettings/pages/rent_monthly.rb @@ -3,10 +3,7 @@ class Form::Lettings::Pages::RentMonthly < ::Form::Page super @id = "rent_monthly" @copy_key = "lettings.income_and_benefits.rent_and_charges" - @depends_on = [ - { "household_charge" => nil, "rent_and_charges_paid_monthly?" => true, "is_carehome?" => false }, - { "household_charge" => 0, "rent_and_charges_paid_monthly?" => true, "is_carehome?" => false }, - ] + @depends_on = depends_on end def questions @@ -18,4 +15,18 @@ class Form::Lettings::Pages::RentMonthly < ::Form::Page Form::Lettings::Questions::TchargeMonthly.new(nil, nil, self), ] end + + def depends_on + if form.start_year_2025_or_later? + [ + { "household_charge" => nil, "rent_and_charges_paid_monthly?" => true }, + { "household_charge" => 0, "rent_and_charges_paid_monthly?" => true }, + ] + else + [ + { "household_charge" => nil, "rent_and_charges_paid_monthly?" => true, "is_carehome?" => false }, + { "household_charge" => 0, "rent_and_charges_paid_monthly?" => true, "is_carehome?" => false }, + ] + end + end end diff --git a/app/models/form/lettings/pages/rent_weekly.rb b/app/models/form/lettings/pages/rent_weekly.rb index 86106cfe3..b40641ebe 100644 --- a/app/models/form/lettings/pages/rent_weekly.rb +++ b/app/models/form/lettings/pages/rent_weekly.rb @@ -3,10 +3,7 @@ class Form::Lettings::Pages::RentWeekly < ::Form::Page super @id = "rent_weekly" @copy_key = "lettings.income_and_benefits.rent_and_charges" - @depends_on = [ - { "rent_and_charges_paid_weekly?" => true, "household_charge" => 0, "is_carehome?" => false }, - { "rent_and_charges_paid_weekly?" => true, "household_charge" => nil, "is_carehome?" => false }, - ] + @depends_on = depends_on end def questions @@ -18,4 +15,18 @@ class Form::Lettings::Pages::RentWeekly < ::Form::Page Form::Lettings::Questions::TchargeWeekly.new(nil, nil, self), ] end + + def depends_on + if form.start_year_2025_or_later? + [ + { "rent_and_charges_paid_weekly?" => true, "household_charge" => 0 }, + { "rent_and_charges_paid_weekly?" => true, "household_charge" => nil }, + ] + else + [ + { "rent_and_charges_paid_weekly?" => true, "household_charge" => 0, "is_carehome?" => false }, + { "rent_and_charges_paid_weekly?" => true, "household_charge" => nil, "is_carehome?" => false }, + ] + end + end end diff --git a/app/models/form/lettings/subsections/income_and_benefits.rb b/app/models/form/lettings/subsections/income_and_benefits.rb index 2be2fb9a5..4ad3003cb 100644 --- a/app/models/form/lettings/subsections/income_and_benefits.rb +++ b/app/models/form/lettings/subsections/income_and_benefits.rb @@ -15,11 +15,7 @@ class Form::Lettings::Subsections::IncomeAndBenefits < ::Form::Subsection Form::Lettings::Pages::BenefitsProportion.new("benefits_proportion", nil, self), Form::Lettings::Pages::RentOrOtherCharges.new(nil, nil, self), Form::Lettings::Pages::RentPeriod.new(nil, nil, self), - Form::Lettings::Pages::CareHomeWeekly.new(nil, nil, self), - Form::Lettings::Pages::CareHomeBiWeekly.new(nil, nil, self), - Form::Lettings::Pages::CareHome4Weekly.new(nil, nil, self), - Form::Lettings::Pages::CareHomeMonthly.new(nil, nil, self), - Form::Lettings::Pages::CareHomeChargesValueCheck.new(nil, nil, self), + carehome_questions, Form::Lettings::Pages::RentWeekly.new(nil, nil, self), Form::Lettings::Pages::RentBiWeekly.new(nil, nil, self), Form::Lettings::Pages::Rent4Weekly.new(nil, nil, self), @@ -30,6 +26,20 @@ class Form::Lettings::Subsections::IncomeAndBenefits < ::Form::Subsection Form::Lettings::Pages::SupchargValueCheck.new(nil, nil, self), Form::Lettings::Pages::Outstanding.new(nil, nil, self), Form::Lettings::Pages::OutstandingAmount.new(nil, nil, self), - ].compact + ].flatten.compact + end + +private + + def carehome_questions + return [] if form.start_year_2025_or_later? + + [ + Form::Lettings::Pages::CareHomeWeekly.new(nil, nil, self), + Form::Lettings::Pages::CareHomeBiWeekly.new(nil, nil, self), + Form::Lettings::Pages::CareHome4Weekly.new(nil, nil, self), + Form::Lettings::Pages::CareHomeMonthly.new(nil, nil, self), + Form::Lettings::Pages::CareHomeChargesValueCheck.new(nil, nil, self), + ] end end diff --git a/spec/models/form/lettings/pages/rent4_weekly_spec.rb b/spec/models/form/lettings/pages/rent4_weekly_spec.rb new file mode 100644 index 000000000..8a8527d6a --- /dev/null +++ b/spec/models/form/lettings/pages/rent4_weekly_spec.rb @@ -0,0 +1,44 @@ +require "rails_helper" + +RSpec.describe Form::Lettings::Pages::Rent4Weekly, type: :model do + subject(:page) { described_class.new(nil, page_definition, subsection) } + + let(:page_definition) { nil } + let(:start_date) { Time.zone.local(2024, 4, 1) } + let(:start_year_2025_or_later) { false } + let(:form) { instance_double(Form, start_date:) } + let(:subsection) { instance_double(Form::Subsection, form:) } + let(:person_index) { 2 } + + before do + allow(form).to receive(:start_year_2025_or_later?).and_return(start_year_2025_or_later) + end + + context "with form before 2025" do + let(:start_date) { Time.zone.local(2024, 4, 1) } + let(:start_year_2025_or_later) { false } + + it "has correct depends_on" do + expect(page.depends_on).to eq( + [ + { "rent_and_charges_paid_every_4_weeks?" => true, "household_charge" => 0, "is_carehome?" => false }, + { "rent_and_charges_paid_every_4_weeks?" => true, "household_charge" => nil, "is_carehome?" => false }, + ], + ) + end + end + + context "with form on or after 2025" do + let(:start_date) { Time.zone.local(2025, 4, 1) } + let(:start_year_2025_or_later) { true } + + it "has correct depends_on" do + expect(page.depends_on).to eq( + [ + { "rent_and_charges_paid_every_4_weeks?" => true, "household_charge" => 0 }, + { "rent_and_charges_paid_every_4_weeks?" => true, "household_charge" => nil }, + ], + ) + end + end +end diff --git a/spec/models/form/lettings/pages/rent_bi_weekly_spec.rb b/spec/models/form/lettings/pages/rent_bi_weekly_spec.rb new file mode 100644 index 000000000..a1975f766 --- /dev/null +++ b/spec/models/form/lettings/pages/rent_bi_weekly_spec.rb @@ -0,0 +1,44 @@ +require "rails_helper" + +RSpec.describe Form::Lettings::Pages::RentBiWeekly, type: :model do + subject(:page) { described_class.new(nil, page_definition, subsection) } + + let(:page_definition) { nil } + let(:start_date) { Time.zone.local(2024, 4, 1) } + let(:start_year_2025_or_later) { false } + let(:form) { instance_double(Form, start_date:) } + let(:subsection) { instance_double(Form::Subsection, form:) } + let(:person_index) { 2 } + + before do + allow(form).to receive(:start_year_2025_or_later?).and_return(start_year_2025_or_later) + end + + context "with form before 2025" do + let(:start_date) { Time.zone.local(2024, 4, 1) } + let(:start_year_2025_or_later) { false } + + it "has correct depends_on" do + expect(page.depends_on).to eq( + [ + { "rent_and_charges_paid_every_2_weeks?" => true, "household_charge" => nil, "is_carehome?" => false }, + { "rent_and_charges_paid_every_2_weeks?" => true, "household_charge" => 0, "is_carehome?" => false }, + ], + ) + end + end + + context "with form on or after 2025" do + let(:start_date) { Time.zone.local(2025, 4, 1) } + let(:start_year_2025_or_later) { true } + + it "has correct depends_on" do + expect(page.depends_on).to eq( + [ + { "rent_and_charges_paid_every_2_weeks?" => true, "household_charge" => nil }, + { "rent_and_charges_paid_every_2_weeks?" => true, "household_charge" => 0 }, + ], + ) + end + end +end diff --git a/spec/models/form/lettings/pages/rent_monthly_spec.rb b/spec/models/form/lettings/pages/rent_monthly_spec.rb new file mode 100644 index 000000000..619fc254e --- /dev/null +++ b/spec/models/form/lettings/pages/rent_monthly_spec.rb @@ -0,0 +1,44 @@ +require "rails_helper" + +RSpec.describe Form::Lettings::Pages::RentMonthly, type: :model do + subject(:page) { described_class.new(nil, page_definition, subsection) } + + let(:page_definition) { nil } + let(:start_date) { Time.zone.local(2024, 4, 1) } + let(:start_year_2025_or_later) { false } + let(:form) { instance_double(Form, start_date:) } + let(:subsection) { instance_double(Form::Subsection, form:) } + let(:person_index) { 2 } + + before do + allow(form).to receive(:start_year_2025_or_later?).and_return(start_year_2025_or_later) + end + + context "with form before 2025" do + let(:start_date) { Time.zone.local(2024, 4, 1) } + let(:start_year_2025_or_later) { false } + + it "has correct depends_on" do + expect(page.depends_on).to eq( + [ + { "rent_and_charges_paid_monthly?" => true, "household_charge" => nil, "is_carehome?" => false }, + { "rent_and_charges_paid_monthly?" => true, "household_charge" => 0, "is_carehome?" => false }, + ], + ) + end + end + + context "with form on or after 2025" do + let(:start_date) { Time.zone.local(2025, 4, 1) } + let(:start_year_2025_or_later) { true } + + it "has correct depends_on" do + expect(page.depends_on).to eq( + [ + { "rent_and_charges_paid_monthly?" => true, "household_charge" => nil }, + { "rent_and_charges_paid_monthly?" => true, "household_charge" => 0 }, + ], + ) + end + end +end diff --git a/spec/models/form/lettings/pages/rent_weekly_spec.rb b/spec/models/form/lettings/pages/rent_weekly_spec.rb new file mode 100644 index 000000000..89bbae37a --- /dev/null +++ b/spec/models/form/lettings/pages/rent_weekly_spec.rb @@ -0,0 +1,44 @@ +require "rails_helper" + +RSpec.describe Form::Lettings::Pages::RentWeekly, type: :model do + subject(:page) { described_class.new(nil, page_definition, subsection) } + + let(:page_definition) { nil } + let(:start_date) { Time.zone.local(2024, 4, 1) } + let(:start_year_2025_or_later) { false } + let(:form) { instance_double(Form, start_date:) } + let(:subsection) { instance_double(Form::Subsection, form:) } + let(:person_index) { 2 } + + before do + allow(form).to receive(:start_year_2025_or_later?).and_return(start_year_2025_or_later) + end + + context "with form before 2025" do + let(:start_date) { Time.zone.local(2024, 4, 1) } + let(:start_year_2025_or_later) { false } + + it "has correct depends_on" do + expect(page.depends_on).to eq( + [ + { "rent_and_charges_paid_weekly?" => true, "household_charge" => 0, "is_carehome?" => false }, + { "rent_and_charges_paid_weekly?" => true, "household_charge" => nil, "is_carehome?" => false }, + ], + ) + end + end + + context "with form on or after 2025" do + let(:start_date) { Time.zone.local(2025, 4, 1) } + let(:start_year_2025_or_later) { true } + + it "has correct depends_on" do + expect(page.depends_on).to eq( + [ + { "rent_and_charges_paid_weekly?" => true, "household_charge" => 0 }, + { "rent_and_charges_paid_weekly?" => true, "household_charge" => nil }, + ], + ) + end + end +end diff --git a/spec/models/form/lettings/subsections/income_and_benefits_spec.rb b/spec/models/form/lettings/subsections/income_and_benefits_spec.rb index 7bdc26bfa..9d78b3216 100644 --- a/spec/models/form/lettings/subsections/income_and_benefits_spec.rb +++ b/spec/models/form/lettings/subsections/income_and_benefits_spec.rb @@ -5,40 +5,77 @@ RSpec.describe Form::Lettings::Subsections::IncomeAndBenefits, type: :model do let(:subsection_id) { nil } let(:subsection_definition) { nil } - let(:form) { instance_double(Form, start_date: Time.zone.local(2024, 4, 1)) } + let(:start_date) { Time.zone.local(2024, 4, 1) } + let(:start_year_2025_or_later) { false } + let(:form) { instance_double(Form, start_date:) } let(:section) { instance_double(Form::Lettings::Sections::RentAndCharges, form:) } + before do + allow(form).to receive(:start_year_2025_or_later?).and_return(start_year_2025_or_later) + end + it "has correct section" do expect(income_and_benefits.section).to eq(section) end - it "has correct pages" do - expect(income_and_benefits.pages.map(&:id)).to eq( - %w[ - income_known - income_amount - net_income_value_check - housing_benefit - benefits_proportion - rent_or_other_charges - rent_period - care_home_weekly - care_home_bi_weekly - care_home_4_weekly - care_home_monthly - care_home_charges_value_check - rent_weekly - rent_bi_weekly - rent_4_weekly - rent_monthly - brent_rent_value_check - scharge_value_check - pscharge_value_check - supcharg_value_check - outstanding - outstanding_amount - ], - ) + context "with 2024 form" do + it "has correct pages" do + expect(income_and_benefits.pages.map(&:id)).to eq( + %w[ + income_known + income_amount + net_income_value_check + housing_benefit + benefits_proportion + rent_or_other_charges + rent_period + care_home_weekly + care_home_bi_weekly + care_home_4_weekly + care_home_monthly + care_home_charges_value_check + rent_weekly + rent_bi_weekly + rent_4_weekly + rent_monthly + brent_rent_value_check + scharge_value_check + pscharge_value_check + supcharg_value_check + outstanding + outstanding_amount + ], + ) + end + end + + context "with 2025 form" do + let(:start_date) { Time.zone.local(2025, 4, 1) } + let(:start_year_2025_or_later) { true } + + it "has correct pages" do + expect(income_and_benefits.pages.map(&:id)).to eq( + %w[ + income_known + income_amount + net_income_value_check + housing_benefit + benefits_proportion + rent_or_other_charges + rent_period + rent_weekly + rent_bi_weekly + rent_4_weekly + rent_monthly + brent_rent_value_check + scharge_value_check + pscharge_value_check + supcharg_value_check + outstanding + outstanding_amount + ], + ) + end end it "has the correct id" do From cabd650dd668c7c55d637b7ffadce9209ce466aa Mon Sep 17 00:00:00 2001 From: Rachael Booth Date: Fri, 10 Jan 2025 14:59:59 +0000 Subject: [PATCH 2/7] CLDC-3833: Update validation on total discount for percentage discounts to include an extra 1000 leeway for rounding errors (#2889) --- .../sales/sale_information_validations.rb | 4 +- .../validations/sales/sale_information.en.yml | 20 +++++----- .../sale_information_validations_spec.rb | 38 ++++++++++++------- 3 files changed, 36 insertions(+), 26 deletions(-) diff --git a/app/models/validations/sales/sale_information_validations.rb b/app/models/validations/sales/sale_information_validations.rb index 4b8948053..f99f6668a 100644 --- a/app/models/validations/sales/sale_information_validations.rb +++ b/app/models/validations/sales/sale_information_validations.rb @@ -144,11 +144,11 @@ module Validations::Sales::SaleInformationValidations return unless record.saledate && record.form.start_year_2024_or_later? return unless record.discount && record.value && record.la - if record.london_property? && record.discount_value > 136_400 + if record.london_property? && record.discount_value > 137_400 %i[discount value la postcode_full uprn].each do |field| record.errors.add field, I18n.t("validations.sales.sale_information.#{field}.value_over_discounted_london_max", discount_value: record.field_formatted_as_currency("discount_value")) end - elsif record.property_not_in_london? && record.discount_value > 102_400 + elsif record.property_not_in_london? && record.discount_value > 103_400 %i[discount value la postcode_full uprn].each do |field| record.errors.add field, I18n.t("validations.sales.sale_information.#{field}.value_over_discounted_max", discount_value: record.field_formatted_as_currency("discount_value")) end diff --git a/config/locales/validations/sales/sale_information.en.yml b/config/locales/validations/sales/sale_information.en.yml index ea17953fb..f29856143 100644 --- a/config/locales/validations/sales/sale_information.en.yml +++ b/config/locales/validations/sales/sale_information.en.yml @@ -47,8 +47,8 @@ en: value: discounted_ownership_value: "The mortgage%{mortgage}%{deposit_and_grant_sentence} added together is %{mortgage_deposit_and_grant_total}.

The full purchase price%{discount_sentence} is %{value_with_discount}.

These two amounts should be the same." outright_sale_value: "The mortgage%{mortgage} and cash deposit (%{deposit}) when added together is %{mortgage_and_deposit_total}.

The full purchase price is %{value}.

These two amounts should be the same." - 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." - value_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." + value_over_discounted_london_max: "The percentage discount multiplied by the purchase price is %{discount_value}. This figure should not be more than £137,400 for properties in London." + value_over_discounted_max: "The percentage discount multiplied by the purchase price is %{discount_value}. This figure should not be more than £103,400 for properties outside of London." non_staircasing_mortgage: mortgage_used: "The mortgage (%{mortgage}) and cash deposit (%{deposit}) added together is %{mortgage_and_deposit_total}.

The full purchase price (%{value}) multiplied by the percentage equity stake purchased (%{equity}) is %{expected_shared_ownership_deposit_value}.

These two amounts should be the same." mortgage_not_used: "The cash deposit is %{deposit}.

The full purchase price (%{value}) multiplied by the percentage bought is %{expected_shared_ownership_deposit_value}.

These two amounts should be the same." @@ -87,8 +87,8 @@ en: mortgage_not_used_socialhomebuy: "The cash deposit (%{deposit}) and cash discount (%{cashdis}) added together is %{deposit_and_discount_total}.

The full purchase price (%{value}) multiplied by the percentage bought (%{equity}) is %{expected_shared_ownership_deposit_value}.

These two amounts should be the same." discount: discounted_ownership_value: "The mortgage%{mortgage}%{deposit_and_grant_sentence} added together is %{mortgage_deposit_and_grant_total}.

The full purchase price%{discount_sentence} is %{value_with_discount}.

These two amounts should be the same." - 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." - value_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." + value_over_discounted_london_max: "The percentage discount multiplied by the purchase price is %{discount_value}. This figure should not be more than £137,400 for properties in London." + value_over_discounted_max: "The percentage discount multiplied by the purchase price is %{discount_value}. This figure should not be more than £103,400 for properties outside of London." grant: discounted_ownership_value: "The mortgage%{mortgage}%{deposit_and_grant_sentence} added together is %{mortgage_deposit_and_grant_total}.

The full purchase price%{discount_sentence} is %{value_with_discount}.

These two amounts should be the same." out_of_range: "Loan, grants or subsidies must be between £9,000 and £16,000." @@ -119,14 +119,14 @@ en: staircase: mortgage_used_value: "You must answer either ‘yes’ or ‘no’ to the question ‘was a mortgage used’ for staircasing transactions." la: - 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." - value_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." + value_over_discounted_london_max: "The percentage discount multiplied by the purchase price is %{discount_value}. This figure should not be more than £137,400 for properties in London." + value_over_discounted_max: "The percentage discount multiplied by the purchase price is %{discount_value}. This figure should not be more than £103,400 for properties outside of London." uprn: - 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." - value_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." + value_over_discounted_london_max: "The percentage discount multiplied by the purchase price is %{discount_value}. This figure should not be more than £137,400 for properties in London." + value_over_discounted_max: "The percentage discount multiplied by the purchase price is %{discount_value}. This figure should not be more than £103,400 for properties outside of London." postcode_full: - 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." - value_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." + value_over_discounted_london_max: "The percentage discount multiplied by the purchase price is %{discount_value}. This figure should not be more than £137,400 for properties in London." + value_over_discounted_max: "The percentage discount multiplied by the purchase price is %{discount_value}. This figure should not be more than £103,400 for properties outside of London." numstair: must_be_greater_than_one: "The number of staircasing transactions must be greater than 1 when this is not the first staircasing transaction." firststair: diff --git a/spec/models/validations/sales/sale_information_validations_spec.rb b/spec/models/validations/sales/sale_information_validations_spec.rb index fabe3c8c5..da49d1936 100644 --- a/spec/models/validations/sales/sale_information_validations_spec.rb +++ b/spec/models/validations/sales/sale_information_validations_spec.rb @@ -795,17 +795,22 @@ RSpec.describe Validations::Sales::SaleInformationValidations do record.la = "E09000001" end - it "adds an error if value * discount is more than 136,400" do + it "adds an error if value * discount is more than 137,400" do + record.value = 200_000 record.discount = 80 + discount_value = "£160,000.00" sale_information_validator.validate_discount_and_value(record) - expect(record.errors["value"]).to include("The percentage discount multiplied by the purchase price is £160,000.00. This figure should not be more than £136,400 for properties in London.") - expect(record.errors["discount"]).to include("The percentage discount multiplied by the purchase price is £160,000.00. This figure should not be more than £136,400 for properties in London.") - expect(record.errors["la"]).to include("The percentage discount multiplied by the purchase price is £160,000.00. This figure should not be more than £136,400 for properties in London.") - expect(record.errors["postcode_full"]).to include("The percentage discount multiplied by the purchase price is £160,000.00. This figure should not be more than £136,400 for properties in London.") - expect(record.errors["uprn"]).to include("The percentage discount multiplied by the purchase price is £160,000.00. This figure should not be more than £136,400 for properties in London.") + expect(record.errors["value"]).to include(I18n.t("validations.sales.sale_information.value.value_over_discounted_london_max", discount_value:)) + expect(record.errors["discount"]).to include(I18n.t("validations.sales.sale_information.discount.value_over_discounted_london_max", discount_value:)) + expect(record.errors["la"]).to include(I18n.t("validations.sales.sale_information.la.value_over_discounted_london_max", discount_value:)) + expect(record.errors["postcode_full"]).to include(I18n.t("validations.sales.sale_information.postcode_full.value_over_discounted_london_max", discount_value:)) + expect(record.errors["uprn"]).to include(I18n.t("validations.sales.sale_information.uprn.value_over_discounted_london_max", discount_value:)) end - it "does not add an error value * discount is less than 136,400" do + it "does not add an error value * discount is less than 137,400" do + record.value = 200_000 + record.discount = 50 + # Discount value: 100,000 sale_information_validator.validate_discount_and_value(record) expect(record.errors["value"]).to be_empty expect(record.errors["discount"]).to be_empty @@ -820,17 +825,22 @@ RSpec.describe Validations::Sales::SaleInformationValidations do record.la = "E06000015" end - it "adds an error if value * discount is more than 136,400" do + it "adds an error if value * discount is more than 103,400" do + record.value = 200_000 record.discount = 52 + discount_value = "£104,000.00" sale_information_validator.validate_discount_and_value(record) - expect(record.errors["value"]).to include("The percentage discount multiplied by the purchase price is £104,000.00. This figure should not be more than £102,400 for properties outside of London.") - expect(record.errors["discount"]).to include("The percentage discount multiplied by the purchase price is £104,000.00. This figure should not be more than £102,400 for properties outside of London.") - expect(record.errors["la"]).to include("The percentage discount multiplied by the purchase price is £104,000.00. This figure should not be more than £102,400 for properties outside of London.") - expect(record.errors["postcode_full"]).to include("The percentage discount multiplied by the purchase price is £104,000.00. This figure should not be more than £102,400 for properties outside of London.") - expect(record.errors["uprn"]).to include("The percentage discount multiplied by the purchase price is £104,000.00. This figure should not be more than £102,400 for properties outside of London.") + expect(record.errors["value"]).to include(I18n.t("validations.sales.sale_information.value.value_over_discounted_max", discount_value:)) + expect(record.errors["discount"]).to include(I18n.t("validations.sales.sale_information.discount.value_over_discounted_max", discount_value:)) + expect(record.errors["la"]).to include(I18n.t("validations.sales.sale_information.la.value_over_discounted_max", discount_value:)) + expect(record.errors["postcode_full"]).to include(I18n.t("validations.sales.sale_information.postcode_full.value_over_discounted_max", discount_value:)) + expect(record.errors["uprn"]).to include(I18n.t("validations.sales.sale_information.uprn.value_over_discounted_max", discount_value:)) end - it "does not add an error value * discount is less than 136,400" do + it "does not add an error value * discount is less than 103,400" do + record.value = 200_000 + record.discount = 50 + # Discount value: 100,000 sale_information_validator.validate_discount_and_value(record) expect(record.errors["value"]).to be_empty expect(record.errors["discount"]).to be_empty From 80f126c49ba1526a7e1045de75e9d91df4f93dd0 Mon Sep 17 00:00:00 2001 From: Rachael Booth Date: Mon, 13 Jan 2025 11:24:07 +0000 Subject: [PATCH 3/7] CLDC-3837: Fix bug with step validation for numeric fields with step 0.1 (#2893) * CLDC-3837: Fix bug with step validation for numeric fields with step 0.1 * Refactor tests * Fix test --- app/models/validations/shared_validations.rb | 17 +-- config/locales/validations/shared.en.yml | 2 + .../validations/shared_validations_spec.rb | 122 +++++++++++------- 3 files changed, 85 insertions(+), 56 deletions(-) diff --git a/app/models/validations/shared_validations.rb b/app/models/validations/shared_validations.rb index da79599ee..7b0ecc420 100644 --- a/app/models/validations/shared_validations.rb +++ b/app/models/validations/shared_validations.rb @@ -54,14 +54,15 @@ module Validations::SharedValidations field = question.check_answer_label || question.id incorrect_accuracy = (value.to_d * 100) % (question.step * 100) != 0 - if question.step < 1 && incorrect_accuracy - record.errors.add question.id.to_sym, I18n.t("validations.shared.numeric.nearest_hundredth", field:) - elsif incorrect_accuracy || value.to_d != value.to_i # if the user enters a value in exponent notation (eg '4e1') the to_i method does not convert this to the correct value - field = question.check_answer_label || question.id - case question.step - when 1 then record.errors.add question.id.to_sym, :not_integer, message: I18n.t("validations.shared.numeric.whole_number", field:) - when 10 then record.errors.add question.id.to_sym, I18n.t("validations.shared.numeric.nearest_ten", field:) - end + next unless incorrect_accuracy + + case question.step + when 0.01 then record.errors.add question.id.to_sym, I18n.t("validations.shared.numeric.nearest_hundredth", field:) + when 0.1 then record.errors.add question.id.to_sym, I18n.t("validations.shared.numeric.nearest_tenth", field:) + when 1 then record.errors.add question.id.to_sym, :not_integer, message: I18n.t("validations.shared.numeric.whole_number", field:) + when 10 then record.errors.add question.id.to_sym, I18n.t("validations.shared.numeric.nearest_ten", field:) + else + record.errors.add question.id.to_sym, I18n.t("validations.shared.numeric.nearest_step", field:, step: question.step) end end end diff --git a/config/locales/validations/shared.en.yml b/config/locales/validations/shared.en.yml index a29d2bd74..ea06636dc 100644 --- a/config/locales/validations/shared.en.yml +++ b/config/locales/validations/shared.en.yml @@ -9,7 +9,9 @@ en: above_min: "%{field} must be at least %{min}." whole_number: "%{field} must be a whole number." nearest_ten: "%{field} must be given to the nearest ten." + nearest_tenth: "%{field} must be given to the nearest tenth." nearest_hundredth: "%{field} must be given to the nearest hundredth." + nearest_step: "${field} must be given to the nearest %{step}." normal_format: "Enter a number." format: "%{field} must be a number." diff --git a/spec/models/validations/shared_validations_spec.rb b/spec/models/validations/shared_validations_spec.rb index 53efc6675..2d9ec4ef3 100644 --- a/spec/models/validations/shared_validations_spec.rb +++ b/spec/models/validations/shared_validations_spec.rb @@ -116,19 +116,23 @@ RSpec.describe Validations::SharedValidations do end describe "validating level of accuracy or rounding for numeric questions" do + let(:sales_log) { build(:sales_log, :completed) } + + before do + income_question = instance_double(Form::Question, step:, type: "numeric", id: "income1", check_answer_label: "Buyer 1’s gross annual income", page: instance_double(Form::Page, routed_to?: true)) + form = instance_double(Form, numeric_questions: [income_question]) + allow(FormHandler.instance).to receive(:get_form).and_return(form) + end + context "when validating a question with a step of 1" do + let(:step) { 1 } + it "adds an error if input is a decimal" do sales_log.income1 = 30_000.5 shared_validator.validate_numeric_step(sales_log) expect(sales_log.errors[:income1]).to include I18n.t("validations.shared.numeric.whole_number", field: "Buyer 1’s gross annual income") end - it "adds an error if the user attempts to input a number in exponent format" do - sales_log.income1 = "3e5" - shared_validator.validate_numeric_step(sales_log) - expect(sales_log.errors[:income1]).to include I18n.t("validations.shared.numeric.whole_number", field: "Buyer 1’s gross annual income") - end - it "does not add an error if input is an integer" do sales_log.income1 = 30_000 shared_validator.validate_numeric_step(sales_log) @@ -137,80 +141,96 @@ RSpec.describe Validations::SharedValidations do end context "when validating a question with a step of 10" do - it "adds an error if input is not a multiple of ten" do - sales_log.savings = 30_005 - sales_log.jointpur = 1 - shared_validator.validate_numeric_step(sales_log) - expect(sales_log.errors[:savings]).to include I18n.t("validations.shared.numeric.nearest_ten", field: "Buyers’ total savings before any deposit paid") - end + let(:step) { 10 } - it "adds an error if the user attempts to input a number in exponent format" do - sales_log.savings = "3e5" - sales_log.jointpur = 1 + it "adds an error if input is not a multiple of ten" do + sales_log.income1 = 30_005 shared_validator.validate_numeric_step(sales_log) - expect(sales_log.errors[:savings]).to include I18n.t("validations.shared.numeric.nearest_ten", field: "Buyers’ total savings before any deposit paid") + expect(sales_log.errors[:income1]).to include I18n.t("validations.shared.numeric.nearest_ten", field: "Buyer 1’s gross annual income") end it "does not add an error if input is a multiple of ten" do - sales_log.savings = 30_000 + sales_log.income1 = 30_000 shared_validator.validate_numeric_step(sales_log) expect(sales_log.errors).to be_empty end end context "when validating a question with a step of 0.01" do + let(:step) { 0.01 } + it "adds an error if input has more than 2 decimal places" do - sales_log.mscharge = 30.7418 + sales_log.income1 = 30_123.7418 shared_validator.validate_numeric_step(sales_log) - expect(sales_log.errors[:mscharge]).to include I18n.t("validations.shared.numeric.nearest_hundredth", field: "Monthly leasehold charges") + expect(sales_log.errors[:income1]).to include I18n.t("validations.shared.numeric.nearest_hundredth", field: "Buyer 1’s gross annual income") end - it "does not add an error if the user attempts to input a number in exponent format" do - sales_log.mscharge = "3e1" + it "does not add an error if input has 2 or fewer decimal places" do + sales_log.income1 = 30_123.74 shared_validator.validate_numeric_step(sales_log) expect(sales_log.errors).to be_empty end + end - it "does not add an error if input has 2 or fewer decimal places" do - sales_log.mscharge = 30.74 + context "when validating a question with a step of 0.1" do + let(:step) { 0.1 } + + it "adds an error if input has more than 1 decimal place" do + sales_log.income1 = 30_123.74 + shared_validator.validate_numeric_step(sales_log) + expect(sales_log.errors[:income1]).to include I18n.t("validations.shared.numeric.nearest_tenth", field: "Buyer 1’s gross annual income") + end + + it "does not add an error if input has 1 or fewer decimal places" do + sales_log.income1 = 30_123.8 shared_validator.validate_numeric_step(sales_log) expect(sales_log.errors).to be_empty end end - %i[sales_log lettings_log].each do |log_type| - describe "validate_owning_organisation_data_sharing_agremeent_signed" do - it "is valid if the Data Protection Confirmation is signed" do - log = build(log_type, :in_progress, owning_organisation: create(:organisation)) + context "when validating a question with an unusual step" do + let(:step) { 0.001 } - expect(log).to be_valid - end + it "adds an appropriate error if input does not match" do + sales_log.income1 = 30_123.7419 + shared_validator.validate_numeric_step(sales_log) + expect(sales_log.errors[:income1]).to include I18n.t("validations.shared.numeric.nearest_step", field: "Buyer 1’s gross annual income", step: 0.001) + end + end + end - it "is valid when owning_organisation nil" do - log = build(log_type, owning_organisation: nil) + %i[sales_log lettings_log].each do |log_type| + describe "validate_owning_organisation_data_sharing_agremeent_signed" do + it "is valid if the Data Protection Confirmation is signed" do + log = build(log_type, :in_progress, owning_organisation: create(:organisation)) - expect(log).to be_valid - end + expect(log).to be_valid + end - it "is not valid if the Data Protection Confirmation is not signed" do - log = build(log_type, owning_organisation: create(:organisation, :without_dpc)) + it "is valid when owning_organisation nil" do + log = build(log_type, owning_organisation: nil) - expect(log).not_to be_valid - expect(log.errors[:owning_organisation_id]).to eq(["The organisation must accept the Data Sharing Agreement before it can be selected as the owning organisation."]) - end + expect(log).to be_valid + end + + it "is not valid if the Data Protection Confirmation is not signed" do + log = build(log_type, owning_organisation: create(:organisation, :without_dpc)) - context "when updating" do - let(:log) { create(log_type, :in_progress) } - let(:org_with_dpc) { create(:organisation) } - let(:org_without_dpc) { create(:organisation, :without_dpc) } + expect(log).not_to be_valid + expect(log.errors[:owning_organisation_id]).to eq(["The organisation must accept the Data Sharing Agreement before it can be selected as the owning organisation."]) + end - it "is valid when changing to another org with a signed Data Protection Confirmation" do - expect { log.owning_organisation = org_with_dpc }.not_to change(log, :valid?) - end + context "when updating" do + let(:log) { create(log_type, :in_progress) } + let(:org_with_dpc) { create(:organisation) } + let(:org_without_dpc) { create(:organisation, :without_dpc) } + + it "is valid when changing to another org with a signed Data Protection Confirmation" do + expect { log.owning_organisation = org_with_dpc }.not_to change(log, :valid?) + end - it "invalid when changing to another org without a signed Data Protection Confirmation" do - expect { log.owning_organisation = org_without_dpc }.to change(log, :valid?).from(true).to(false).and(change { log.errors[:owning_organisation_id] }.to(["The organisation must accept the Data Sharing Agreement before it can be selected as the owning organisation."])) - end + it "invalid when changing to another org without a signed Data Protection Confirmation" do + expect { log.owning_organisation = org_without_dpc }.to change(log, :valid?).from(true).to(false).and(change { log.errors[:owning_organisation_id] }.to(["The organisation must accept the Data Sharing Agreement before it can be selected as the owning organisation."])) end end end @@ -229,6 +249,12 @@ RSpec.describe Validations::SharedValidations do expect(sales_log.errors[:income1]).to include I18n.t("validations.shared.numeric.format", field: "Buyer 1’s gross annual income") end + it "does not allow exponent format" do + sales_log.income1 = "1e4" + shared_validator.validate_numeric_input(sales_log) + expect(sales_log.errors[:income1]).to include I18n.t("validations.shared.numeric.format", field: "Buyer 1’s gross annual income") + end + it "allows a digit" do sales_log.income1 = "300" shared_validator.validate_numeric_input(sales_log) From 7455440e0154f0d383679a44f5058d3feea251c4 Mon Sep 17 00:00:00 2001 From: kosiakkatrina <54268893+kosiakkatrina@users.noreply.github.com> Date: Mon, 13 Jan 2025 14:41:05 +0000 Subject: [PATCH 4/7] CLDC-3822 Update date validations for 2025 (#2886) * Update date validations for 2025 * Refactor date validations, account for leap years --- app/models/validations/date_validations.rb | 55 ++++---- .../locales/validations/lettings/date.en.yml | 4 + .../validations/date_validations_spec.rb | 123 +++++++++++------- 3 files changed, 110 insertions(+), 72 deletions(-) diff --git a/app/models/validations/date_validations.rb b/app/models/validations/date_validations.rb index 7462290b6..f69f41cdd 100644 --- a/app/models/validations/date_validations.rb +++ b/app/models/validations/date_validations.rb @@ -2,53 +2,56 @@ module Validations::DateValidations include Validations::SharedValidations def validate_property_major_repairs(record) - date_valid?("mrcdate", record) - if record["startdate"].present? && record["mrcdate"].present? && record["startdate"] < record["mrcdate"] - record.errors.add :mrcdate, I18n.t("validations.lettings.date.mrcdate.before_tenancy_start") - end + return unless record["mrcdate"].present? && date_valid?("mrcdate", record) if is_rsnvac_first_let?(record) && record["mrcdate"].present? record.errors.add :mrcdate, I18n.t("validations.lettings.date.mrcdate.not_first_let") end + return unless record["startdate"].present? && date_valid?("startdate", record) - if record["mrcdate"].present? && record["startdate"].present? && record["startdate"].to_date - record["mrcdate"].to_date > 3650 + if record["startdate"].present? && record["mrcdate"].present? && record["startdate"] < record["mrcdate"] + record.errors.add :mrcdate, I18n.t("validations.lettings.date.mrcdate.before_tenancy_start") + record.errors.add :startdate, I18n.t("validations.lettings.date.startdate.after_major_repair_date") + end + + if record.form.start_year_2025_or_later? + if record["startdate"].to_date - 20.years > record["mrcdate"].to_date + record.errors.add :mrcdate, I18n.t("validations.lettings.date.mrcdate.twenty_years_before_tenancy_start") + record.errors.add :startdate, I18n.t("validations.lettings.date.startdate.twenty_years_after_mrc_date") + end + elsif record["startdate"].to_date - 10.years > record["mrcdate"].to_date record.errors.add :mrcdate, I18n.t("validations.lettings.date.mrcdate.ten_years_before_tenancy_start") + record.errors.add :startdate, I18n.t("validations.lettings.date.startdate.ten_years_after_mrc_date") end end def validate_property_void_date(record) - if record["voiddate"].present? && record["startdate"].present? && record["startdate"].to_date - record["voiddate"].to_date > 3650 - record.errors.add :voiddate, I18n.t("validations.lettings.date.void_date.ten_years_before_tenancy_start") - end - - if record["voiddate"].present? && record["startdate"].present? && record["startdate"].to_date < record["voiddate"].to_date - record.errors.add :voiddate, I18n.t("validations.lettings.date.void_date.before_tenancy_start") - end + return unless record["voiddate"].present? && date_valid?("voiddate", record) - if record["voiddate"].present? && record["mrcdate"].present? && record["mrcdate"].to_date < record["voiddate"].to_date + if record["mrcdate"].present? && record["mrcdate"].to_date < record["voiddate"].to_date record.errors.add :voiddate, :after_mrcdate, message: I18n.t("validations.lettings.date.void_date.after_mrcdate") record.errors.add :mrcdate, I18n.t("validations.lettings.date.mrcdate.before_void_date") end - end - - def validate_startdate(record) - return unless record.startdate && date_valid?("startdate", record) + return unless record["startdate"].present? && date_valid?("startdate", record) - if record["voiddate"].present? && record.startdate < record["voiddate"] + if record["startdate"].to_date < record["voiddate"].to_date + record.errors.add :voiddate, I18n.t("validations.lettings.date.void_date.before_tenancy_start") record.errors.add :startdate, I18n.t("validations.lettings.date.startdate.after_void_date") end - if record["mrcdate"].present? && record.startdate < record["mrcdate"] - record.errors.add :startdate, I18n.t("validations.lettings.date.startdate.after_major_repair_date") - end - - if record["voiddate"].present? && record["startdate"].to_date - record["voiddate"].to_date > 3650 + if record.form.start_year_2025_or_later? + if record["startdate"].to_date - 20.years > record["voiddate"].to_date + record.errors.add :voiddate, I18n.t("validations.lettings.date.void_date.twenty_years_before_tenancy_start") + record.errors.add :startdate, I18n.t("validations.lettings.date.startdate.twenty_years_after_void_date") + end + elsif record["startdate"].to_date - 10.years > record["voiddate"].to_date + record.errors.add :voiddate, I18n.t("validations.lettings.date.void_date.ten_years_before_tenancy_start") record.errors.add :startdate, I18n.t("validations.lettings.date.startdate.ten_years_after_void_date") end + end - if record["mrcdate"].present? && record["startdate"].to_date - record["mrcdate"].to_date > 3650 - record.errors.add :startdate, I18n.t("validations.lettings.date.startdate.ten_years_after_mrc_date") - end + def validate_startdate(record) + date_valid?("startdate", record) end private diff --git a/config/locales/validations/lettings/date.en.yml b/config/locales/validations/lettings/date.en.yml index 54c53996f..1e46dba7b 100644 --- a/config/locales/validations/lettings/date.en.yml +++ b/config/locales/validations/lettings/date.en.yml @@ -7,14 +7,18 @@ en: after_major_repair_date: "Enter a tenancy start date that is after the major repair date." ten_years_after_void_date: "Enter a tenancy start date that is no more than 10 years after the void date." ten_years_after_mrc_date: "Enter a tenancy start date that is no more than 10 years after the major repairs completion date." + twenty_years_after_void_date: "Enter a tenancy start date that is no more than 20 years after the void date." + twenty_years_after_mrc_date: "Enter a tenancy start date that is no more than 20 years after the major repairs completion date." mrcdate: before_tenancy_start: "Enter a major repairs date that is before the tenancy start date." not_first_let: "Major repairs date must not be completed if the tenancy is a first let." ten_years_before_tenancy_start: "Enter a major repairs completion date that is no more than 10 years before the tenancy start date." + twenty_years_before_tenancy_start: "Enter a major repairs completion date that is no more than 20 years before the tenancy start date." before_void_date: "Major repairs date must be after the void date if provided." void_date: ten_years_before_tenancy_start: "Enter a void date no more than 10 years before the tenancy start date." + twenty_years_before_tenancy_start: "Enter a void date no more than 20 years before the tenancy start date." before_tenancy_start: "Enter a void date that is before the tenancy start date." after_mrcdate: "Void date must be before the major repairs date if provided." diff --git a/spec/models/validations/date_validations_spec.rb b/spec/models/validations/date_validations_spec.rb index 3ca259b16..b88a75eb2 100644 --- a/spec/models/validations/date_validations_spec.rb +++ b/spec/models/validations/date_validations_spec.rb @@ -21,22 +21,6 @@ RSpec.describe Validations::DateValidations do expect(record.errors["startdate"]).to be_empty end - it "validates that the tenancy start date is after the void date if it has a void date" do - record.startdate = Time.zone.local(2022, 1, 1) - record.voiddate = Time.zone.local(2022, 2, 1) - date_validator.validate_startdate(record) - expect(record.errors["startdate"]) - .to include(match I18n.t("validations.lettings.date.startdate.after_void_date")) - end - - it "validates that the tenancy start date is after the major repair date if it has a major repair date" do - record.startdate = Time.zone.local(2022, 1, 1) - record.mrcdate = Time.zone.local(2022, 2, 1) - date_validator.validate_startdate(record) - expect(record.errors["startdate"]) - .to include(match I18n.t("validations.lettings.date.startdate.after_major_repair_date")) - end - it "produces no error when the tenancy start date is before the end date of the chosen scheme if it has an end date" do record.startdate = Time.zone.today - 30.days record.scheme = scheme @@ -59,6 +43,8 @@ RSpec.describe Validations::DateValidations do date_validator.validate_property_major_repairs(record) expect(record.errors["mrcdate"]) .to include(match I18n.t("validations.lettings.date.mrcdate.before_tenancy_start")) + expect(record.errors["startdate"]) + .to include(match I18n.t("validations.lettings.date.startdate.after_major_repair_date")) end it "must be before the tenancy start date" do @@ -68,23 +54,44 @@ RSpec.describe Validations::DateValidations do expect(record.errors["mrcdate"]).to be_empty end - it "cannot be more than 10 years before the tenancy start date" do - record.startdate = Time.zone.local(2022, 2, 1) - record.mrcdate = Time.zone.local(2012, 1, 1) - date_validator.validate_property_major_repairs(record) - date_validator.validate_startdate(record) - expect(record.errors["mrcdate"]) - .to include(match I18n.t("validations.lettings.date.mrcdate.ten_years_before_tenancy_start")) - expect(record.errors["startdate"]) - .to include(match I18n.t("validations.lettings.date.startdate.ten_years_after_mrc_date")) + context "with 2024 logs or earlier" do + it "cannot be more than 10 years before the tenancy start date" do + record.startdate = Time.zone.local(2024, 2, 1) + record.mrcdate = Time.zone.local(2014, 1, 31) + date_validator.validate_property_major_repairs(record) + expect(record.errors["mrcdate"]) + .to include(match I18n.t("validations.lettings.date.mrcdate.ten_years_before_tenancy_start")) + expect(record.errors["startdate"]) + .to include(match I18n.t("validations.lettings.date.startdate.ten_years_after_mrc_date")) + end + + it "must be within 10 years of the tenancy start date" do + record.startdate = Time.zone.local(2024, 2, 1) + record.mrcdate = Time.zone.local(2014, 2, 1) + date_validator.validate_property_major_repairs(record) + expect(record.errors["mrcdate"]).to be_empty + expect(record.errors["startdate"]).to be_empty + end end - it "must be within 10 years of the tenancy start date" do - record.startdate = Time.zone.local(2022, 2, 1) - record.mrcdate = Time.zone.local(2012, 3, 1) - date_validator.validate_property_major_repairs(record) - expect(record.errors["mrcdate"]).to be_empty - expect(record.errors["startdate"]).to be_empty + context "with 2025 logs or later" do + it "cannot be more than 20 years before the tenancy start date" do + record.startdate = Time.zone.local(2026, 2, 1) + record.mrcdate = Time.zone.local(2006, 1, 31) + date_validator.validate_property_major_repairs(record) + expect(record.errors["mrcdate"]) + .to include(match I18n.t("validations.lettings.date.mrcdate.twenty_years_before_tenancy_start")) + expect(record.errors["startdate"]) + .to include(match I18n.t("validations.lettings.date.startdate.twenty_years_after_mrc_date")) + end + + it "must be within 20 years of the tenancy start date" do + record.startdate = Time.zone.local(2026, 2, 1) + record.mrcdate = Time.zone.local(2006, 2, 1) + date_validator.validate_property_major_repairs(record) + expect(record.errors["mrcdate"]).to be_empty + expect(record.errors["startdate"]).to be_empty + end end context "when reason for vacancy is first let of property" do @@ -130,6 +137,8 @@ RSpec.describe Validations::DateValidations do date_validator.validate_property_void_date(record) expect(record.errors["voiddate"]) .to include(match I18n.t("validations.lettings.date.void_date.before_tenancy_start")) + expect(record.errors["startdate"]) + .to include(match I18n.t("validations.lettings.date.startdate.after_void_date")) end it "must be before the tenancy start date" do @@ -139,23 +148,45 @@ RSpec.describe Validations::DateValidations do expect(record.errors["voiddate"]).to be_empty end - it "cannot be more than 10 years before the tenancy start date" do - record.startdate = Time.zone.local(2022, 2, 1) - record.voiddate = Time.zone.local(2012, 1, 1) - date_validator.validate_property_void_date(record) - date_validator.validate_startdate(record) - expect(record.errors["voiddate"]) - .to include(match I18n.t("validations.lettings.date.void_date.ten_years_before_tenancy_start")) - expect(record.errors["startdate"]) - .to include(match I18n.t("validations.lettings.date.startdate.ten_years_after_void_date")) + context "with 2024 logs or earlier" do + it "cannot be more than 10 years before the tenancy start date" do + record.startdate = Time.zone.local(2024, 2, 1) + record.voiddate = Time.zone.local(2014, 1, 31) + date_validator.validate_property_void_date(record) + expect(record.errors["voiddate"]) + .to include(match I18n.t("validations.lettings.date.void_date.ten_years_before_tenancy_start")) + expect(record.errors["startdate"]) + .to include(match I18n.t("validations.lettings.date.startdate.ten_years_after_void_date")) + end + + it "must be within 10 years of the tenancy start date" do + record.startdate = Time.zone.local(2024, 2, 1) + record.voiddate = Time.zone.local(2014, 2, 1) + date_validator.validate_property_void_date(record) + expect(record.errors["voiddate"]).to be_empty + expect(record.errors["startdate"]).to be_empty + end end - it "must be within 10 years of the tenancy start date" do - record.startdate = Time.zone.local(2022, 2, 1) - record.voiddate = Time.zone.local(2012, 3, 1) - date_validator.validate_property_void_date(record) - expect(record.errors["voiddate"]).to be_empty - expect(record.errors["startdate"]).to be_empty + context "with 2025 logs or later" do + it "cannot be more than 20 years before the tenancy start date" do + record.startdate = Time.zone.local(2026, 2, 1) + record.voiddate = Time.zone.local(2006, 1, 31) + date_validator.validate_property_void_date(record) + date_validator.validate_startdate(record) + expect(record.errors["voiddate"]) + .to include(match I18n.t("validations.lettings.date.void_date.twenty_years_before_tenancy_start")) + expect(record.errors["startdate"]) + .to include(match I18n.t("validations.lettings.date.startdate.twenty_years_after_void_date")) + end + + it "must be within 20 years of the tenancy start date" do + record.startdate = Time.zone.local(2026, 2, 1) + record.voiddate = Time.zone.local(2006, 2, 1) + date_validator.validate_property_void_date(record) + expect(record.errors["voiddate"]).to be_empty + expect(record.errors["startdate"]).to be_empty + end end context "when major repairs have been carried out" do From b1a384e454ef266c41a7220c9514c2cd44eb1f5c Mon Sep 17 00:00:00 2001 From: kosiakkatrina <54268893+kosiakkatrina@users.noreply.github.com> Date: Mon, 13 Jan 2025 14:41:40 +0000 Subject: [PATCH 5/7] Update person relationship questions (#2892) --- .../lettings/pages/person_lead_partner.rb | 12 ++ .../form/lettings/questions/person_partner.rb | 30 ++++ .../subsections/household_characteristics.rb | 22 ++- .../lettings/household_characteristics.en.yml | 28 ++-- .../pages/person_lead_partner_spec.rb | 51 ++++++ .../lettings/questions/person_partner_spec.rb | 57 +++++++ .../household_characteristics_spec.rb | 156 ++++++++++++++++++ 7 files changed, 335 insertions(+), 21 deletions(-) create mode 100644 app/models/form/lettings/pages/person_lead_partner.rb create mode 100644 app/models/form/lettings/questions/person_partner.rb create mode 100644 spec/models/form/lettings/pages/person_lead_partner_spec.rb create mode 100644 spec/models/form/lettings/questions/person_partner_spec.rb diff --git a/app/models/form/lettings/pages/person_lead_partner.rb b/app/models/form/lettings/pages/person_lead_partner.rb new file mode 100644 index 000000000..30613d976 --- /dev/null +++ b/app/models/form/lettings/pages/person_lead_partner.rb @@ -0,0 +1,12 @@ +class Form::Lettings::Pages::PersonLeadPartner < ::Form::Page + def initialize(id, hsh, subsection, person_index:) + super(id, hsh, subsection) + @id = "person_#{person_index}_lead_partner" + @depends_on = [{ "details_known_#{person_index}" => 0 }] + @person_index = person_index + end + + def questions + @questions ||= [Form::Lettings::Questions::PersonPartner.new(nil, nil, self, person_index: @person_index)] + end +end diff --git a/app/models/form/lettings/questions/person_partner.rb b/app/models/form/lettings/questions/person_partner.rb new file mode 100644 index 000000000..25c2d72c1 --- /dev/null +++ b/app/models/form/lettings/questions/person_partner.rb @@ -0,0 +1,30 @@ +class Form::Lettings::Questions::PersonPartner < ::Form::Question + def initialize(id, hsh, page, person_index:) + super(id, hsh, page) + @id = "relat#{person_index}" + @type = "radio" + @check_answers_card_number = person_index + @answer_options = answer_options + @person_index = person_index + @question_number = question_number + end + + def answer_options + { + "P" => { "value" => "Yes" }, + "X" => { "value" => "No" }, + "R" => { "value" => "Tenant prefers not to say" }, + } + end + + def question_number + base_question_number = case form.start_date.year + when 2023 + 30 + else + 29 + end + + base_question_number + (4 * @person_index) + end +end diff --git a/app/models/form/lettings/subsections/household_characteristics.rb b/app/models/form/lettings/subsections/household_characteristics.rb index 61334d84c..a454ffed5 100644 --- a/app/models/form/lettings/subsections/household_characteristics.rb +++ b/app/models/form/lettings/subsections/household_characteristics.rb @@ -32,7 +32,7 @@ class Form::Lettings::Subsections::HouseholdCharacteristics < ::Form::Subsection Form::Lettings::Pages::LeadTenantUnderRetirementValueCheck.new("working_situation_lead_tenant_under_retirement_value_check", nil, self), Form::Lettings::Pages::LeadTenantOverRetirementValueCheck.new("working_situation_lead_tenant_over_retirement_value_check", nil, self), Form::Lettings::Pages::PersonKnown.new(nil, nil, self, person_index: 2), - Form::Lettings::Pages::PersonRelationshipToLead.new(nil, nil, self, person_index: 2), + relationship_question(person_index: 2), (Form::Lettings::Pages::PartnerUnder16ValueCheck.new("relationship_2_partner_under_16_value_check", nil, self, person_index: 2) if form.start_year_2024_or_later?), (Form::Lettings::Pages::MultiplePartnersValueCheck.new("relationship_2_multiple_partners_value_check", nil, self, person_index: 2) if form.start_year_2024_or_later?), Form::Lettings::Pages::PersonAge.new(nil, nil, self, person_index: 2), @@ -52,7 +52,7 @@ class Form::Lettings::Subsections::HouseholdCharacteristics < ::Form::Subsection Form::Lettings::Pages::PersonUnderRetirementValueCheck.new("working_situation_2_under_retirement_value_check", nil, self, person_index: 2), Form::Lettings::Pages::PersonOverRetirementValueCheck.new("working_situation_2_over_retirement_value_check", nil, self, person_index: 2), Form::Lettings::Pages::PersonKnown.new(nil, nil, self, person_index: 3), - Form::Lettings::Pages::PersonRelationshipToLead.new(nil, nil, self, person_index: 3), + relationship_question(person_index: 3), (Form::Lettings::Pages::PartnerUnder16ValueCheck.new("relationship_3_partner_under_16_value_check", nil, self, person_index: 3) if form.start_year_2024_or_later?), (Form::Lettings::Pages::MultiplePartnersValueCheck.new("relationship_3_multiple_partners_value_check", nil, self, person_index: 3) if form.start_year_2024_or_later?), Form::Lettings::Pages::PersonAge.new(nil, nil, self, person_index: 3), @@ -72,7 +72,7 @@ class Form::Lettings::Subsections::HouseholdCharacteristics < ::Form::Subsection Form::Lettings::Pages::PersonUnderRetirementValueCheck.new("working_situation_3_under_retirement_value_check", nil, self, person_index: 3), Form::Lettings::Pages::PersonOverRetirementValueCheck.new("working_situation_3_over_retirement_value_check", nil, self, person_index: 3), Form::Lettings::Pages::PersonKnown.new(nil, nil, self, person_index: 4), - Form::Lettings::Pages::PersonRelationshipToLead.new(nil, nil, self, person_index: 4), + relationship_question(person_index: 4), (Form::Lettings::Pages::PartnerUnder16ValueCheck.new("relationship_4_partner_under_16_value_check", nil, self, person_index: 4) if form.start_year_2024_or_later?), (Form::Lettings::Pages::MultiplePartnersValueCheck.new("relationship_4_multiple_partners_value_check", nil, self, person_index: 4) if form.start_year_2024_or_later?), Form::Lettings::Pages::PersonAge.new(nil, nil, self, person_index: 4), @@ -92,7 +92,7 @@ class Form::Lettings::Subsections::HouseholdCharacteristics < ::Form::Subsection Form::Lettings::Pages::PersonUnderRetirementValueCheck.new("working_situation_4_under_retirement_value_check", nil, self, person_index: 4), Form::Lettings::Pages::PersonOverRetirementValueCheck.new("working_situation_4_over_retirement_value_check", nil, self, person_index: 4), Form::Lettings::Pages::PersonKnown.new(nil, nil, self, person_index: 5), - Form::Lettings::Pages::PersonRelationshipToLead.new(nil, nil, self, person_index: 5), + relationship_question(person_index: 5), (Form::Lettings::Pages::PartnerUnder16ValueCheck.new("relationship_5_partner_under_16_value_check", nil, self, person_index: 5) if form.start_year_2024_or_later?), (Form::Lettings::Pages::MultiplePartnersValueCheck.new("relationship_5_multiple_partners_value_check", nil, self, person_index: 5) if form.start_year_2024_or_later?), Form::Lettings::Pages::PersonAge.new(nil, nil, self, person_index: 5), @@ -112,7 +112,7 @@ class Form::Lettings::Subsections::HouseholdCharacteristics < ::Form::Subsection Form::Lettings::Pages::PersonUnderRetirementValueCheck.new("working_situation_5_under_retirement_value_check", nil, self, person_index: 5), Form::Lettings::Pages::PersonOverRetirementValueCheck.new("working_situation_5_over_retirement_value_check", nil, self, person_index: 5), Form::Lettings::Pages::PersonKnown.new(nil, nil, self, person_index: 6), - Form::Lettings::Pages::PersonRelationshipToLead.new(nil, nil, self, person_index: 6), + relationship_question(person_index: 6), (Form::Lettings::Pages::PartnerUnder16ValueCheck.new("relationship_6_partner_under_16_value_check", nil, self, person_index: 6) if form.start_year_2024_or_later?), (Form::Lettings::Pages::MultiplePartnersValueCheck.new("relationship_6_multiple_partners_value_check", nil, self, person_index: 6) if form.start_year_2024_or_later?), Form::Lettings::Pages::PersonAge.new(nil, nil, self, person_index: 6), @@ -132,7 +132,7 @@ class Form::Lettings::Subsections::HouseholdCharacteristics < ::Form::Subsection Form::Lettings::Pages::PersonUnderRetirementValueCheck.new("working_situation_6_under_retirement_value_check", nil, self, person_index: 6), Form::Lettings::Pages::PersonOverRetirementValueCheck.new("working_situation_6_over_retirement_value_check", nil, self, person_index: 6), Form::Lettings::Pages::PersonKnown.new(nil, nil, self, person_index: 7), - Form::Lettings::Pages::PersonRelationshipToLead.new(nil, nil, self, person_index: 7), + relationship_question(person_index: 7), (Form::Lettings::Pages::PartnerUnder16ValueCheck.new("relationship_7_partner_under_16_value_check", nil, self, person_index: 7) if form.start_year_2024_or_later?), (Form::Lettings::Pages::MultiplePartnersValueCheck.new("relationship_7_multiple_partners_value_check", nil, self, person_index: 7) if form.start_year_2024_or_later?), Form::Lettings::Pages::PersonAge.new(nil, nil, self, person_index: 7), @@ -152,7 +152,7 @@ class Form::Lettings::Subsections::HouseholdCharacteristics < ::Form::Subsection Form::Lettings::Pages::PersonUnderRetirementValueCheck.new("working_situation_7_under_retirement_value_check", nil, self, person_index: 7), Form::Lettings::Pages::PersonOverRetirementValueCheck.new("working_situation_7_over_retirement_value_check", nil, self, person_index: 7), Form::Lettings::Pages::PersonKnown.new(nil, nil, self, person_index: 8), - Form::Lettings::Pages::PersonRelationshipToLead.new(nil, nil, self, person_index: 8), + relationship_question(person_index: 8), (Form::Lettings::Pages::PartnerUnder16ValueCheck.new("relationship_8_partner_under_16_value_check", nil, self, person_index: 8) if form.start_year_2024_or_later?), (Form::Lettings::Pages::MultiplePartnersValueCheck.new("relationship_8_multiple_partners_value_check", nil, self, person_index: 8) if form.start_year_2024_or_later?), Form::Lettings::Pages::PersonAge.new(nil, nil, self, person_index: 8), @@ -173,4 +173,12 @@ class Form::Lettings::Subsections::HouseholdCharacteristics < ::Form::Subsection Form::Lettings::Pages::PersonOverRetirementValueCheck.new("working_situation_8_over_retirement_value_check", nil, self, person_index: 8), ].compact end + + def relationship_question(person_index:) + if form.start_year_2025_or_later? + Form::Lettings::Pages::PersonLeadPartner.new(nil, nil, self, person_index:) + else + Form::Lettings::Pages::PersonRelationshipToLead.new(nil, nil, self, person_index:) + end + end end diff --git a/config/locales/forms/2025/lettings/household_characteristics.en.yml b/config/locales/forms/2025/lettings/household_characteristics.en.yml index b6d7ad7e9..79646b32b 100644 --- a/config/locales/forms/2025/lettings/household_characteristics.en.yml +++ b/config/locales/forms/2025/lettings/household_characteristics.en.yml @@ -84,9 +84,9 @@ en: relat2: page_header: "" - check_answer_label: "Person 2’s relationship to the lead tenant" + check_answer_label: "Person 2 lead tenant’s partner" hint_text: "" - question_text: "What is person 2’s relationship to the lead tenant?" + question_text: "Is tenant 2 the partner of tenant 1?" age2: page_header: "" @@ -119,9 +119,9 @@ en: relat3: page_header: "" - check_answer_label: "Person 3’s relationship to the lead tenant" + check_answer_label: "Person 3 lead tenant’s partner" hint_text: "" - question_text: "What is person 3’s relationship to the lead tenant?" + question_text: "Is tenant 3 the partner of tenant 1?" age3: page_header: "" @@ -154,9 +154,9 @@ en: relat4: page_header: "" - check_answer_label: "Person 4’s relationship to the lead tenant" + check_answer_label: "Person 4 lead tenant’s partner" hint_text: "" - question_text: "What is person 4’s relationship to the lead tenant?" + question_text: "Is tenant 4 the partner of tenant 1?" age4: page_header: "" @@ -189,9 +189,9 @@ en: relat5: page_header: "" - check_answer_label: "Person 5’s relationship to the lead tenant" + check_answer_label: "Person 5 lead tenant’s partner" hint_text: "" - question_text: "What is person 5’s relationship to the lead tenant?" + question_text: "Is tenant 5 the partner of tenant 1?" age5: page_header: "" @@ -224,9 +224,9 @@ en: relat6: page_header: "" - check_answer_label: "Person 6’s relationship to the lead tenant" + check_answer_label: "Person 6 lead tenant’s partner" hint_text: "" - question_text: "What is person 6’s relationship to the lead tenant?" + question_text: "Is tenant 6 the partner of tenant 1?" age6: page_header: "" @@ -259,9 +259,9 @@ en: relat7: page_header: "" - check_answer_label: "Person 7’s relationship to the lead tenant" + check_answer_label: "Person 7 lead tenant’s partner" hint_text: "" - question_text: "What is person 7’s relationship to the lead tenant?" + question_text: "Is tenant 7 the partner of tenant 1?" age7: page_header: "" @@ -294,9 +294,9 @@ en: relat8: page_header: "" - check_answer_label: "Person 8’s relationship to the lead tenant" + check_answer_label: "Person 8 lead tenant’s partner" hint_text: "" - question_text: "What is person 8’s relationship to the lead tenant?" + question_text: "Is tenant 8 the partner of tenant 1?" age8: page_header: "" diff --git a/spec/models/form/lettings/pages/person_lead_partner_spec.rb b/spec/models/form/lettings/pages/person_lead_partner_spec.rb new file mode 100644 index 000000000..88aa3095d --- /dev/null +++ b/spec/models/form/lettings/pages/person_lead_partner_spec.rb @@ -0,0 +1,51 @@ +require "rails_helper" + +RSpec.describe Form::Lettings::Pages::PersonLeadPartner, type: :model do + subject(:page) { described_class.new(nil, page_definition, subsection, person_index:) } + + let(:page_definition) { nil } + let(:subsection) { instance_double(Form::Subsection, form: instance_double(Form, start_date: Time.zone.local(2024, 4, 1), start_year_2025_or_later?: true)) } + let(:person_index) { 2 } + + it "has correct subsection" do + expect(page.subsection).to eq(subsection) + end + + it "has the correct description" do + expect(page.description).to be nil + end + + context "with person 2" do + it "has correct questions" do + expect(page.questions.map(&:id)).to eq(%w[relat2]) + end + + it "has the correct id" do + expect(page.id).to eq("person_2_lead_partner") + end + + it "has correct depends_on" do + expect(page.depends_on).to eq( + [{ "details_known_2" => 0 }], + ) + end + end + + context "with person 3" do + let(:person_index) { 3 } + + it "has correct questions" do + expect(page.questions.map(&:id)).to eq(%w[relat3]) + end + + it "has the correct id" do + expect(page.id).to eq("person_3_lead_partner") + end + + it "has correct depends_on" do + expect(page.depends_on).to eq( + [{ "details_known_3" => 0 }], + ) + end + end +end diff --git a/spec/models/form/lettings/questions/person_partner_spec.rb b/spec/models/form/lettings/questions/person_partner_spec.rb new file mode 100644 index 000000000..7e2d177bd --- /dev/null +++ b/spec/models/form/lettings/questions/person_partner_spec.rb @@ -0,0 +1,57 @@ +require "rails_helper" + +RSpec.describe Form::Lettings::Questions::PersonPartner, type: :model do + subject(:question) { described_class.new(nil, question_definition, page, person_index:) } + + let(:question_definition) { nil } + let(:page) { instance_double(Form::Page, subsection: instance_double(Form::Subsection, form: instance_double(Form, start_date: Time.zone.local(2025, 4, 4), start_year_2025_or_later?: true))) } + let(:person_index) { 2 } + + it "has correct page" do + expect(question.page).to eq(page) + end + + it "has the correct type" do + expect(question.type).to eq("radio") + end + + it "is not marked as derived" do + expect(question.derived?(nil)).to be false + end + + it "has the correct answer_options" do + expect(question.answer_options).to eq("P" => { "value" => "Yes" }, + "X" => { "value" => "No" }, + "R" => { "value" => "Tenant prefers not to say" }) + end + + it "has correct conditional for" do + expect(question.conditional_for).to be nil + end + + it "has the correct hidden_in_check_answers" do + expect(question.hidden_in_check_answers).to be nil + end + + context "with person 2" do + it "has the correct id" do + expect(question.id).to eq("relat2") + end + + it "has the correct check_answers_card_number" do + expect(question.check_answers_card_number).to eq(2) + end + end + + context "with person 3" do + let(:person_index) { 3 } + + it "has the correct id" do + expect(question.id).to eq("relat3") + end + + it "has the correct check_answers_card_number" do + expect(question.check_answers_card_number).to eq(3) + end + end +end diff --git a/spec/models/form/lettings/subsections/household_characteristics_spec.rb b/spec/models/form/lettings/subsections/household_characteristics_spec.rb index b45f86fce..5aab3514c 100644 --- a/spec/models/form/lettings/subsections/household_characteristics_spec.rb +++ b/spec/models/form/lettings/subsections/household_characteristics_spec.rb @@ -10,6 +10,7 @@ RSpec.describe Form::Lettings::Subsections::HouseholdCharacteristics, type: :mod before do allow(section).to receive(:form).and_return(form) + allow(form).to receive(:start_year_2025_or_later?).and_return(false) end it "has correct section" do @@ -304,6 +305,161 @@ RSpec.describe Form::Lettings::Subsections::HouseholdCharacteristics, type: :mod end end + context "with start year >= 2025" do + before do + allow(form).to receive(:start_year_2024_or_later?).and_return(true) + allow(form).to receive(:start_year_2025_or_later?).and_return(true) + end + + it "has correct pages" do + expect(household_characteristics.pages.map(&:id)).to eq( + %w[ + household_members + no_females_pregnant_household_lead_hhmemb_value_check + females_in_soft_age_range_in_pregnant_household_lead_hhmemb_value_check + lead_tenant_age + no_females_pregnant_household_lead_age_value_check + females_in_soft_age_range_in_pregnant_household_lead_age_value_check + age_lead_tenant_under_retirement_value_check + age_lead_tenant_over_retirement_value_check + lead_tenant_gender_identity + no_females_pregnant_household_lead_value_check + females_in_soft_age_range_in_pregnant_household_lead_value_check + gender_lead_tenant_over_retirement_value_check + lead_tenant_ethnic_group + lead_tenant_ethnic_background_arab + lead_tenant_ethnic_background_asian + lead_tenant_ethnic_background_black + lead_tenant_ethnic_background_mixed + lead_tenant_ethnic_background_white + lead_tenant_nationality + lead_tenant_working_situation + working_situation_lead_tenant_under_retirement_value_check + working_situation_lead_tenant_over_retirement_value_check + person_2_known + person_2_lead_partner + relationship_2_partner_under_16_value_check + relationship_2_multiple_partners_value_check + person_2_age + no_females_pregnant_household_person_2_age_value_check + females_in_soft_age_range_in_pregnant_household_person_2_age_value_check + age_2_under_retirement_value_check + age_2_over_retirement_value_check + age_2_partner_under_16_value_check + person_2_gender_identity + no_females_pregnant_household_person_2_value_check + females_in_soft_age_range_in_pregnant_household_person_2_value_check + gender_2_over_retirement_value_check + person_2_working_situation + working_situation_2_under_retirement_value_check + working_situation_2_over_retirement_value_check + person_3_known + person_3_lead_partner + relationship_3_partner_under_16_value_check + relationship_3_multiple_partners_value_check + person_3_age + no_females_pregnant_household_person_3_age_value_check + females_in_soft_age_range_in_pregnant_household_person_3_age_value_check + age_3_under_retirement_value_check + age_3_over_retirement_value_check + age_3_partner_under_16_value_check + person_3_gender_identity + no_females_pregnant_household_person_3_value_check + females_in_soft_age_range_in_pregnant_household_person_3_value_check + gender_3_over_retirement_value_check + person_3_working_situation + working_situation_3_under_retirement_value_check + working_situation_3_over_retirement_value_check + person_4_known + person_4_lead_partner + relationship_4_partner_under_16_value_check + relationship_4_multiple_partners_value_check + person_4_age + no_females_pregnant_household_person_4_age_value_check + females_in_soft_age_range_in_pregnant_household_person_4_age_value_check + age_4_under_retirement_value_check + age_4_over_retirement_value_check + age_4_partner_under_16_value_check + person_4_gender_identity + no_females_pregnant_household_person_4_value_check + females_in_soft_age_range_in_pregnant_household_person_4_value_check + gender_4_over_retirement_value_check + person_4_working_situation + working_situation_4_under_retirement_value_check + working_situation_4_over_retirement_value_check + person_5_known + person_5_lead_partner + relationship_5_partner_under_16_value_check + relationship_5_multiple_partners_value_check + person_5_age + no_females_pregnant_household_person_5_age_value_check + females_in_soft_age_range_in_pregnant_household_person_5_age_value_check + age_5_under_retirement_value_check + age_5_over_retirement_value_check + age_5_partner_under_16_value_check + person_5_gender_identity + no_females_pregnant_household_person_5_value_check + females_in_soft_age_range_in_pregnant_household_person_5_value_check + gender_5_over_retirement_value_check + person_5_working_situation + working_situation_5_under_retirement_value_check + working_situation_5_over_retirement_value_check + person_6_known + person_6_lead_partner + relationship_6_partner_under_16_value_check + relationship_6_multiple_partners_value_check + person_6_age + no_females_pregnant_household_person_6_age_value_check + females_in_soft_age_range_in_pregnant_household_person_6_age_value_check + age_6_under_retirement_value_check + age_6_over_retirement_value_check + age_6_partner_under_16_value_check + person_6_gender_identity + no_females_pregnant_household_person_6_value_check + females_in_soft_age_range_in_pregnant_household_person_6_value_check + gender_6_over_retirement_value_check + person_6_working_situation + working_situation_6_under_retirement_value_check + working_situation_6_over_retirement_value_check + person_7_known + person_7_lead_partner + relationship_7_partner_under_16_value_check + relationship_7_multiple_partners_value_check + person_7_age + no_females_pregnant_household_person_7_age_value_check + females_in_soft_age_range_in_pregnant_household_person_7_age_value_check + age_7_under_retirement_value_check + age_7_over_retirement_value_check + age_7_partner_under_16_value_check + person_7_gender_identity + no_females_pregnant_household_person_7_value_check + females_in_soft_age_range_in_pregnant_household_person_7_value_check + gender_7_over_retirement_value_check + person_7_working_situation + working_situation_7_under_retirement_value_check + working_situation_7_over_retirement_value_check + person_8_known + person_8_lead_partner + relationship_8_partner_under_16_value_check + relationship_8_multiple_partners_value_check + person_8_age + no_females_pregnant_household_person_8_age_value_check + females_in_soft_age_range_in_pregnant_household_person_8_age_value_check + age_8_under_retirement_value_check + age_8_over_retirement_value_check + age_8_partner_under_16_value_check + person_8_gender_identity + no_females_pregnant_household_person_8_value_check + females_in_soft_age_range_in_pregnant_household_person_8_value_check + gender_8_over_retirement_value_check + person_8_working_situation + working_situation_8_under_retirement_value_check + working_situation_8_over_retirement_value_check + ], + ) + end + end + it "has the correct id" do expect(household_characteristics.id).to eq("household_characteristics") end From ddebebee30ee1b786783fd560e29522ec05dd565 Mon Sep 17 00:00:00 2001 From: kosiakkatrina <54268893+kosiakkatrina@users.noreply.github.com> Date: Tue, 14 Jan 2025 09:02:16 +0000 Subject: [PATCH 6/7] Remove irrelevant 2023 checks (#2895) * Remove irrelevant 2023 checks * Update/remove tests --- .../lettings_log_variables.rb | 2 +- .../derived_variables/sales_log_variables.rb | 2 +- app/models/form/question.rb | 2 +- .../bulk_upload_form/prepare_your_file.rb | 2 - app/models/lettings_log.rb | 4 +- app/models/sales_log.rb | 25 +--------- .../validations/financial_validations.rb | 2 +- .../validations/household_validations.rb | 2 +- .../sales/financial_validations.rb | 2 +- .../sales/household_validations.rb | 2 - .../forms/prepare_your_file_2023.html.erb | 46 ------------------- .../forms/prepare_your_file_2023.html.erb | 40 ---------------- .../bulk_upload_shared/guidance.html.erb | 21 ++------- spec/features/bulk_upload_sales_logs_spec.rb | 14 +++--- spec/models/sales_log_spec.rb | 8 ---- .../validations/financial_validations_spec.rb | 14 ------ ...lk_upload_lettings_logs_controller_spec.rb | 1 + .../bulk_upload_sales_logs_controller_spec.rb | 1 + 18 files changed, 20 insertions(+), 170 deletions(-) delete mode 100644 app/views/bulk_upload_lettings_logs/forms/prepare_your_file_2023.html.erb delete mode 100644 app/views/bulk_upload_sales_logs/forms/prepare_your_file_2023.html.erb diff --git a/app/models/derived_variables/lettings_log_variables.rb b/app/models/derived_variables/lettings_log_variables.rb index ced530b17..6d50bb5ff 100644 --- a/app/models/derived_variables/lettings_log_variables.rb +++ b/app/models/derived_variables/lettings_log_variables.rb @@ -346,7 +346,7 @@ private end def address_answered_without_uprn? - [address_line1, town_or_city].all?(&:present?) && uprn.nil? && form.start_date.year >= 2023 + [address_line1, town_or_city].all?(&:present?) && uprn.nil? end def get_lar diff --git a/app/models/derived_variables/sales_log_variables.rb b/app/models/derived_variables/sales_log_variables.rb index 6e12ec488..ef4997283 100644 --- a/app/models/derived_variables/sales_log_variables.rb +++ b/app/models/derived_variables/sales_log_variables.rb @@ -226,7 +226,7 @@ private end def address_answered_without_uprn? - [address_line1, town_or_city].all?(&:present?) && uprn.nil? && form.start_date.year >= 2023 + [address_line1, town_or_city].all?(&:present?) && uprn.nil? end def soctenant_from_prevten_values diff --git a/app/models/form/question.rb b/app/models/form/question.rb index 05eec89dd..a91187003 100644 --- a/app/models/form/question.rb +++ b/app/models/form/question.rb @@ -276,7 +276,7 @@ class Form::Question end def question_number_string(hidden: false) - if @question_number && !hidden && form.start_date.year >= 2023 + if @question_number && !hidden "Q#{@question_number}" end end diff --git a/app/models/forms/bulk_upload_form/prepare_your_file.rb b/app/models/forms/bulk_upload_form/prepare_your_file.rb index b89367d9f..911daa4fe 100644 --- a/app/models/forms/bulk_upload_form/prepare_your_file.rb +++ b/app/models/forms/bulk_upload_form/prepare_your_file.rb @@ -11,8 +11,6 @@ module Forms def view_path case year - when 2023 - "bulk_upload_#{log_type}_logs/forms/prepare_your_file_2023" when 2024 "bulk_upload_#{log_type}_logs/forms/prepare_your_file_2024" end diff --git a/app/models/lettings_log.rb b/app/models/lettings_log.rb index 67cafb75b..3ec0d6bf7 100644 --- a/app/models/lettings_log.rb +++ b/app/models/lettings_log.rb @@ -670,8 +670,7 @@ class LettingsLog < Log ["owning_organisation_id", "startdate", "tenancycode", - form.start_date.year < 2023 || uprn.blank? ? "postcode_full" : nil, - form.start_date.year >= 2023 && uprn.present? ? "uprn" : nil, + uprn.blank? ? "postcode_full" : "uprn", "scheme_id", "location_id", "age1", @@ -884,7 +883,6 @@ private def should_process_uprn_change? return unless uprn return unless startdate - return unless collection_start_year_for_date(startdate) >= 2023 uprn_changed? || startdate_changed? end diff --git a/app/models/sales_log.rb b/app/models/sales_log.rb index d03425ee4..f7604b11e 100644 --- a/app/models/sales_log.rb +++ b/app/models/sales_log.rb @@ -129,33 +129,12 @@ class SalesLog < Log def dynamically_not_required not_required = [] - not_required << "proplen" if proplen_optional? - not_required << "mortlen" if mortlen_optional? - not_required << "frombeds" if frombeds_optional? not_required << "deposit" if form.start_year_2024_or_later? && stairowned_100? not_required += %w[address_line2 county] not_required end - def proplen_optional? - return false unless collection_start_year - - collection_start_year < 2023 - end - - def mortlen_optional? - return false unless collection_start_year - - collection_start_year < 2023 - end - - def frombeds_optional? - return false unless collection_start_year - - collection_start_year < 2023 - end - def unresolved false end @@ -449,7 +428,6 @@ class SalesLog < Log def should_process_uprn_change? return unless uprn return unless saledate - return unless collection_start_year_for_date(saledate) >= 2023 uprn_changed? || saledate_changed? end @@ -514,8 +492,7 @@ class SalesLog < Log "age1", "sex1", "ecstat1", - form.start_date.year < 2023 || uprn.blank? ? "postcode_full" : nil, - form.start_date.year >= 2023 && uprn.present? ? "uprn" : nil].compact + uprn.blank? ? "postcode_full" : "uprn"].compact end def soctenant_is_inferred? diff --git a/app/models/validations/financial_validations.rb b/app/models/validations/financial_validations.rb index 73b389f4c..82b3fae01 100644 --- a/app/models/validations/financial_validations.rb +++ b/app/models/validations/financial_validations.rb @@ -25,7 +25,7 @@ module Validations::FinancialValidations end def validate_net_income(record) - if record.ecstat1 && record.hhmemb && record.weekly_net_income && record.startdate && record.form.start_date.year >= 2023 + if record.ecstat1 && record.hhmemb && record.weekly_net_income && record.startdate if record.weekly_net_income > record.applicable_income_range.hard_max frequency = record.form.get_question("incfreq", record).label_from_value(record.incfreq).downcase hard_max = format_as_currency(record.applicable_income_range.hard_max) diff --git a/app/models/validations/household_validations.rb b/app/models/validations/household_validations.rb index cf0ae009e..b4fa934dc 100644 --- a/app/models/validations/household_validations.rb +++ b/app/models/validations/household_validations.rb @@ -201,7 +201,7 @@ module Validations::HouseholdValidations def validate_layear_and_prevloc(record) return unless record.layear && record.la && record.prevloc && record.collection_start_year - if record.la == record.prevloc && record.layear == 1 && record.collection_start_year >= 2023 + if record.la == record.prevloc && record.layear == 1 record.errors.add :layear, :renewal_just_moved, message: I18n.t("validations.lettings.household.layear.same_la_just_moved_to_area") record.errors.add :la, :renewal_just_moved, message: I18n.t("validations.lettings.household.la.same_la_just_moved_to_area") record.errors.add :postcode_full, :renewal_just_moved, message: I18n.t("validations.lettings.household.postcode_full.same_la_just_moved_to_area") diff --git a/app/models/validations/sales/financial_validations.rb b/app/models/validations/sales/financial_validations.rb index 91d4c31b7..e5d8232f0 100644 --- a/app/models/validations/sales/financial_validations.rb +++ b/app/models/validations/sales/financial_validations.rb @@ -82,7 +82,7 @@ module Validations::Sales::FinancialValidations def validate_child_income(record) return unless record.income2 && record.ecstat2 - if record.income2.positive? && is_economic_status_child?(record.ecstat2) && record.form.start_date.year >= 2023 + if record.income2.positive? && is_economic_status_child?(record.ecstat2) record.errors.add :ecstat2, I18n.t("validations.sales.financial.ecstat2.child_has_income") record.errors.add :income2, I18n.t("validations.sales.financial.income2.child_has_income") end diff --git a/app/models/validations/sales/household_validations.rb b/app/models/validations/sales/household_validations.rb index 175474098..e5a66f935 100644 --- a/app/models/validations/sales/household_validations.rb +++ b/app/models/validations/sales/household_validations.rb @@ -13,8 +13,6 @@ module Validations::Sales::HouseholdValidations end def validate_buyers_living_in_property(record) - return unless record.form.start_date.year >= 2023 - if record.buyers_will_live_in? && record.buyer_one_will_not_live_in_property? && record.buyer_two_will_not_live_in_property? record.errors.add :buylivein, I18n.t("validations.sales.household.buylivein.buyers_will_live_in_property_values_inconsistent") record.errors.add :buy1livein, I18n.t("validations.sales.household.buy1livein.buyers_will_live_in_property_values_inconsistent") diff --git a/app/views/bulk_upload_lettings_logs/forms/prepare_your_file_2023.html.erb b/app/views/bulk_upload_lettings_logs/forms/prepare_your_file_2023.html.erb deleted file mode 100644 index f8549807b..000000000 --- a/app/views/bulk_upload_lettings_logs/forms/prepare_your_file_2023.html.erb +++ /dev/null @@ -1,46 +0,0 @@ -<% content_for :before_content do %> - <%= govuk_back_link href: @form.back_path %> -<% end %> - -
-
- <%= form_with model: @form, scope: :form, url: bulk_upload_lettings_log_path(id: "prepare-your-file"), method: :patch do |f| %> - <%= f.hidden_field :year %> - - Upload lettings logs in bulk (<%= @form.year_combo %>) -

Prepare your file

-

<%= govuk_link_to "Read the full guidance", bulk_upload_lettings_log_path(id: "guidance", form: { year: @form.year }, referrer: "prepare-your-file") %> before you start if you have not used bulk upload before.

- -

Download template

- -

Use one of these templates to upload logs for 2023/24:

-
    -
  • - <%= govuk_link_to "Download the new template", @form.template_path %>: In this template, the questions are in the same order as the 2023/24 paper form and web form. -
  • -
-

There are 7 or 8 rows of content in the templates. These rows are called the ‘headers’. They contain the CORE form questions and guidance about which questions are required and how to format your answers.

- -

Create your file

- -
    -
  • Fill in the template with data from your housing management system. Your data should go below the headers, with one row per log. Leave column A blank - the bulk upload fields start in column B.
  • -
  • Make sure each column of your data aligns with the matching headers above. You may need to reorder your data.
  • -
  • Use the <%= govuk_link_to "Lettings #{@form.year_combo} Bulk Upload Specification", @form.specification_path %> to check your data is in the correct format.
  • -
  • Username field: To assign a log to someone else, enter the email address they use to log into CORE.
  • -
  • If you are using the new template, keep the headers. If you are using the legacy template, you can either keep or remove the headers. If you remove the headers, you should also remove the blank column A.
  • -
- - <%= govuk_inset_text(text: "You can upload both general needs and supported housing logs in the same file for 2023 to 2024 data.") %> - -

Save your file

- -
    -
  • Save your file as a CSV.
  • -
  • Your file should now be ready to upload.
  • -
- - <%= f.govuk_submit class: "govuk-!-margin-top-7" %> - <% end %> -
-
diff --git a/app/views/bulk_upload_sales_logs/forms/prepare_your_file_2023.html.erb b/app/views/bulk_upload_sales_logs/forms/prepare_your_file_2023.html.erb deleted file mode 100644 index 427a835e8..000000000 --- a/app/views/bulk_upload_sales_logs/forms/prepare_your_file_2023.html.erb +++ /dev/null @@ -1,40 +0,0 @@ -<% content_for :before_content do %> - <%= govuk_back_link href: @form.back_path %> -<% end %> - -
-
- <%= form_with model: @form, scope: :form, url: bulk_upload_sales_log_path(id: "prepare-your-file"), method: :patch do |f| %> - <%= f.hidden_field :year %> - - Upload sales logs in bulk (<%= @form.year_combo %>) -

Prepare your file

-

<%= govuk_link_to "Read the full guidance", bulk_upload_sales_log_path(id: "guidance", form: { year: @form.year }, referrer: "prepare-your-file") %> before you start if you have not used bulk upload before.

- -

Download template

- -

Use one of these templates to upload logs for 2023/24:

-
    -
  • <%= govuk_link_to "Download the new template", @form.template_path %>: In this template, the questions are in the same order as the 2023/24 paper form and web form.
  • -
-

There are 7 or 8 rows of content in the templates. These rows are called the ‘headers’. They contain the CORE form questions and guidance about which questions are required and how to format your answers.

- -

Create your file

-
    -
  • Fill in the template with data from your housing management system. Your data should go below the headers, with one row per log. The bulk upload fields start at column B. Leave column A blank.
  • -
  • Make sure each column of your data aligns with the matching headers above. You may need to reorder your data.
  • -
  • Use the <%= govuk_link_to "Sales #{@form.year_combo} Bulk Upload Specification", @form.specification_path %> to check your data is in the correct format.
  • -
  • Username field: To assign a log to someone else, enter the email address they use to log into CORE.
  • -
  • If you are using the new template, keep the headers. If you are using the legacy template, you can either keep or remove the headers. If you remove the headers, you should also remove the blank column A.
  • -
- -

Save your file

-
    -
  • Save your file as a CSV.
  • -
  • Your file should now be ready to upload.
  • -
- - <%= f.govuk_submit %> - <% end %> -
-
diff --git a/app/views/bulk_upload_shared/guidance.html.erb b/app/views/bulk_upload_shared/guidance.html.erb index 54e8063f0..1463f63b9 100644 --- a/app/views/bulk_upload_shared/guidance.html.erb +++ b/app/views/bulk_upload_shared/guidance.html.erb @@ -28,29 +28,14 @@ <%= accordion.with_section(heading_text: "Using the bulk upload template") do %>

For each collection year, we publish a bulk upload template and specification.

- <% if @form.year == 2023 %> -

The bulk upload templates contain 7 or 8 rows of ‘headers’ with information about how to fill in the template, including:

- <% else %> -

The bulk upload templates contain 8 rows of ‘headers’ with information about how to fill in the template, including:

- <% end %> +

The bulk upload templates contain 8 rows of ‘headers’ with information about how to fill in the template, including:

<%= govuk_list ["the CORE form questions and their field numbers", "each field’s valid responses", "if/when certain fields can be left blank", "which fields are used to check for duplicate logs"], type: :bullet %>

You can paste your data below the headers or copy the headers and insert them above the data in your file. The bulk upload fields start at column B. Leave column A blank.

Make sure that each column of data aligns with the corresponding question in the headers. We recommend ordering your data to match the headers, but you can also reorder the headers to match your data. When processing the file, we check what each column of data represents based on the headers above.

- <% if @form.year == 2023 %> -

For 2023/24 uploads, there are 2 templates to choose from, a new template and a legacy template. They outline suggested ways of ordering your data.

-

You must include the headers in your file when you upload, unless your data matches the exact order of the legacy template. If you choose to remove the headers, you must also remove the blank column A.

- -

New template: In this template, the questions are in the same order as the 2023/24 paper form and web form. Use this template if your organisation is new to bulk upload or if your housing management system matches the new column ordering.

-

<%= govuk_link_to "Download the lettings bulk upload template (2023 to 2024) – New question ordering", @form.lettings_template_path %>

-

<%= govuk_link_to "Download the sales bulk upload template (2023 to 2024) – New question ordering", @form.sales_template_path %>

- -

Legacy template: In this template, the questions are in the same order as the 2022/23 template, with new questions added on to the end. Use this template if you have not updated your system to match the new template yet.

- <% else %> -

<%= govuk_link_to "Download the lettings bulk upload template (2024 to 2025)", @form.lettings_template_path %>

-

<%= govuk_link_to "Download the sales bulk upload template (2024 to 2025)", @form.sales_template_path %>

- <% end %> +

<%= govuk_link_to "Download the lettings bulk upload template (2024 to 2025)", @form.lettings_template_path %>

+

<%= govuk_link_to "Download the sales bulk upload template (2024 to 2025)", @form.sales_template_path %>

<% end %> <%= accordion.with_section(heading_text: "Using the bulk upload specification") do %> diff --git a/spec/features/bulk_upload_sales_logs_spec.rb b/spec/features/bulk_upload_sales_logs_spec.rb index 1ff0d9fb0..1816b6720 100644 --- a/spec/features/bulk_upload_sales_logs_spec.rb +++ b/spec/features/bulk_upload_sales_logs_spec.rb @@ -22,7 +22,7 @@ RSpec.describe "Bulk upload sales log" do # rubocop:disable RSpec/AnyInstance context "when during crossover period" do before do - Timecop.freeze(2023, 5, 1) + Timecop.freeze(2024, 5, 1) end after do @@ -38,15 +38,15 @@ RSpec.describe "Bulk upload sales log" do click_button("Continue") expect(page).to have_content("You must select a collection period to upload for") - choose("2023 to 2024") + choose("2024 to 2025") click_button("Continue") click_link("Back") - expect(page.find_field("form-year-2023-field")).to be_checked + expect(page.find_field("form-year-2024-field")).to be_checked click_button("Continue") - expect(page).to have_content("Upload sales logs in bulk (2023 to 2024)") + expect(page).to have_content("Upload sales logs in bulk (2024 to 2025)") click_button("Continue") expect(page).to have_content("Upload your file") @@ -80,7 +80,7 @@ RSpec.describe "Bulk upload sales log" do expect(page).to have_content("Which year") click_button("Continue") click_button("Continue") - choose("2023 to 2024") + choose("2024 to 2025") click_button("Continue") click_button("Continue") @@ -96,7 +96,7 @@ RSpec.describe "Bulk upload sales log" do context "when not in crossover period" do before do - Timecop.freeze(2024, 2, 1) + Timecop.freeze(2025, 2, 1) end after do @@ -108,7 +108,7 @@ RSpec.describe "Bulk upload sales log" do expect(page).to have_link("Upload sales logs in bulk") click_link("Upload sales logs in bulk") - expect(page).to have_content("Upload sales logs in bulk (2023 to 2024)") + expect(page).to have_content("Upload sales logs in bulk (2024 to 2025)") click_button("Continue") expect(page).to have_content("Upload your file") diff --git a/spec/models/sales_log_spec.rb b/spec/models/sales_log_spec.rb index 20eb0b2a6..3e6d6405d 100644 --- a/spec/models/sales_log_spec.rb +++ b/spec/models/sales_log_spec.rb @@ -120,14 +120,6 @@ RSpec.describe SalesLog, type: :model do allow(Time).to receive(:now).and_return(Time.zone.local(2023, 5, 1)) end - it "is set to completed for a log with a saledate before 23/24" do - completed_sales_log.update!(proplen: nil, proplen_asked: 0, saledate: Time.zone.local(2022, 5, 1)) - expect(completed_sales_log.in_progress?).to be(false) - expect(completed_sales_log.not_started?).to be(false) - expect(completed_sales_log.completed?).to be(true) - expect(completed_sales_log.deleted?).to be(false) - end - it "is set to in_progress for a log with a saledate after 23/24" do completed_sales_log.update!(proplen: nil, proplen_asked: 0, saledate: Time.zone.local(2023, 5, 1)) expect(completed_sales_log.in_progress?).to be(true) diff --git a/spec/models/validations/financial_validations_spec.rb b/spec/models/validations/financial_validations_spec.rb index 282e050a2..7151c4c9d 100644 --- a/spec/models/validations/financial_validations_spec.rb +++ b/spec/models/validations/financial_validations_spec.rb @@ -338,20 +338,6 @@ RSpec.describe Validations::FinancialValidations do expect(record.errors["ecstat#{n}"]).to be_empty end end - - context "when the net income is lower than the hard min for their employment status for 22/23 collection" do - it "does not add an error" do - record.startdate = Time.zone.local(2022, 5, 1) - record.earnings = 50 - record.incfreq = 1 - record.hhmemb = 1 - record.ecstat1 = 1 - financial_validator.validate_net_income(record) - expect(record.errors["earnings"]).to be_empty - expect(record.errors["ecstat1"]).to be_empty - expect(record.errors["hhmemb"]).to be_empty - end - end end end diff --git a/spec/requests/bulk_upload_lettings_logs_controller_spec.rb b/spec/requests/bulk_upload_lettings_logs_controller_spec.rb index c9a22768d..abdea7079 100644 --- a/spec/requests/bulk_upload_lettings_logs_controller_spec.rb +++ b/spec/requests/bulk_upload_lettings_logs_controller_spec.rb @@ -112,6 +112,7 @@ RSpec.describe BulkUploadLettingsLogsController, type: :request do context "when requesting the previous year in a crossover period" do before do + allow(Time.zone).to receive(:now).and_return(Time.zone.now + 1.year) allow(FormHandler.instance).to receive(:lettings_in_crossover_period?).and_return(true) end diff --git a/spec/requests/bulk_upload_sales_logs_controller_spec.rb b/spec/requests/bulk_upload_sales_logs_controller_spec.rb index 4c20482be..a2d6e7ef4 100644 --- a/spec/requests/bulk_upload_sales_logs_controller_spec.rb +++ b/spec/requests/bulk_upload_sales_logs_controller_spec.rb @@ -112,6 +112,7 @@ RSpec.describe BulkUploadSalesLogsController, type: :request do context "when requesting the previous year in a crossover period" do before do + allow(Time.zone).to receive(:now).and_return(Time.zone.now + 1.year) allow(FormHandler.instance).to receive(:sales_in_crossover_period?).and_return(true) end From 19c5deb1d31ebef0f6394667d530113ae95e939c Mon Sep 17 00:00:00 2001 From: kosiakkatrina <54268893+kosiakkatrina@users.noreply.github.com> Date: Tue, 14 Jan 2025 09:02:57 +0000 Subject: [PATCH 7/7] CLDC-3817 Only run net income validations when applicable_income_range exists (#2882) * Only run net income validations when applicable_income_range exists * Check that income ranges exist --- app/models/lettings_log.rb | 2 +- app/models/sales_log.rb | 4 ++-- app/models/validations/soft_validations.rb | 4 ++-- .../bulk_upload/lettings/year2024/row_parser_spec.rb | 9 +++++++++ 4 files changed, 14 insertions(+), 5 deletions(-) diff --git a/app/models/lettings_log.rb b/app/models/lettings_log.rb index 3ec0d6bf7..c8505b310 100644 --- a/app/models/lettings_log.rb +++ b/app/models/lettings_log.rb @@ -240,7 +240,7 @@ class LettingsLog < Log end def applicable_income_range - return unless ecstat1 && hhmemb + return unless ecstat1 && hhmemb && ALLOWED_INCOME_RANGES[ecstat1] range = ALLOWED_INCOME_RANGES[ecstat1].clone diff --git a/app/models/sales_log.rb b/app/models/sales_log.rb index f7604b11e..49ba9f81c 100644 --- a/app/models/sales_log.rb +++ b/app/models/sales_log.rb @@ -419,9 +419,9 @@ class SalesLog < Log def income_soft_min_for_ecstat(ecstat_field) economic_status_code = public_send(ecstat_field) - return unless ALLOWED_INCOME_RANGES_SALES + return unless ALLOWED_INCOME_RANGES_SALES && ALLOWED_INCOME_RANGES_SALES[economic_status_code] - soft_min = ALLOWED_INCOME_RANGES_SALES[economic_status_code]&.soft_min + soft_min = ALLOWED_INCOME_RANGES_SALES[economic_status_code].soft_min format_as_currency(soft_min) end diff --git a/app/models/validations/soft_validations.rb b/app/models/validations/soft_validations.rb index 1a2c61138..9dc8828e8 100644 --- a/app/models/validations/soft_validations.rb +++ b/app/models/validations/soft_validations.rb @@ -16,13 +16,13 @@ module Validations::SoftValidations }.freeze def net_income_in_soft_max_range? - return unless weekly_net_income && ecstat1 && hhmemb + return unless weekly_net_income && ecstat1 && hhmemb && applicable_income_range weekly_net_income.between?(applicable_income_range.soft_max, applicable_income_range.hard_max) end def net_income_in_soft_min_range? - return unless weekly_net_income && ecstat1 && hhmemb + return unless weekly_net_income && ecstat1 && hhmemb && applicable_income_range weekly_net_income.between?(applicable_income_range.hard_min, applicable_income_range.soft_min) end diff --git a/spec/services/bulk_upload/lettings/year2024/row_parser_spec.rb b/spec/services/bulk_upload/lettings/year2024/row_parser_spec.rb index 357d661b7..01529a80b 100644 --- a/spec/services/bulk_upload/lettings/year2024/row_parser_spec.rb +++ b/spec/services/bulk_upload/lettings/year2024/row_parser_spec.rb @@ -1915,6 +1915,15 @@ RSpec.describe BulkUpload::Lettings::Year2024::RowParser do expect(parser.errors.where(:field_125, category: :soft_validation).first.message).to eql("You told us the rent is £120.00 every week. This is higher than we would expect.") end end + + context "when an invalid ecstat1 is given" do + let(:attributes) { setup_section_params.merge({ field_46: 11, field_119: 123, field_118: 1 }) } + + it "does not run net income soft validations validation" do + parser.valid? + expect(parser.errors.where(:field_46).count).to be(1) + end + end end describe "log_already_exists?" do