diff --git a/app/models/lettings_log.rb b/app/models/lettings_log.rb index 0ac9f728d..2e6b800eb 100644 --- a/app/models/lettings_log.rb +++ b/app/models/lettings_log.rb @@ -542,7 +542,7 @@ class LettingsLog < Log reason == 1 end - def receives_housing_benefit_only? + def receives_housing_benefit? # 1: Housing benefit hb == 1 end @@ -551,13 +551,7 @@ class LettingsLog < Log hb == 3 end - # Option 8 has been removed starting from 22/23 - def receives_housing_benefit_and_universal_credit? - # 8: Housing benefit and Universal Credit (without housing element) - hb == 8 - end - - def receives_uc_with_housing_element_excl_housing_benefit? + def receives_universal_credit # 6: Universal Credit with housing element (excluding housing benefit) hb == 6 end @@ -572,12 +566,11 @@ class LettingsLog < Log end def receives_housing_related_benefits? - if collection_start_year <= 2021 - receives_housing_benefit_only? || receives_uc_with_housing_element_excl_housing_benefit? || - receives_housing_benefit_and_universal_credit? - else - receives_housing_benefit_only? || receives_uc_with_housing_element_excl_housing_benefit? - end + receives_housing_benefit? || receives_universal_credit + end + + def no_household_income_comes_from_benefits? + benefits == 3 end def local_housing_referral? diff --git a/app/models/validations/financial_validations.rb b/app/models/validations/financial_validations.rb index 3dd6890be..a5794a5e3 100644 --- a/app/models/validations/financial_validations.rb +++ b/app/models/validations/financial_validations.rb @@ -175,6 +175,15 @@ module Validations::FinancialValidations end end + def validate_housing_benefits_matches_income_proportion(record) + return unless record.hb && record.benefits && record.form.start_year_2026_or_later? + + if (record.receives_universal_credit || record.receives_housing_benefit?) && record.no_household_income_comes_from_benefits? + record.errors.add :hb, I18n.t("validations.lettings.financial.hb.housing_benefits_not_match_income_source") + record.errors.add :benefits, I18n.t("validations.lettings.financial.benefits.housing_benefits_not_match_income_source") + end + end + private def validate_charges(record) diff --git a/config/locales/validations/lettings/financial.en.yml b/config/locales/validations/lettings/financial.en.yml index d91610602..6f83e85aa 100644 --- a/config/locales/validations/lettings/financial.en.yml +++ b/config/locales/validations/lettings/financial.en.yml @@ -12,6 +12,7 @@ en: outstanding_amount_not_expected: "Answer must be ‘yes’ as you have answered the outstanding amount question." benefits: part_or_full_time: "Answer cannot be ‘all’ for income from Universal Credit, state pensions or benefits if the tenant or their partner works part-time or full-time." + housing_benefits_not_match_income_source: "You answered that none of the household’s income is from Universal Credit, state pensions or benefits, but also that the tenant is likely to be receiving Universal Credit or housing benefit." earnings: over_hard_max: "The household’s income cannot be greater than %{hard_max} per week given the household’s working situation." under_hard_min: "The household’s income cannot be less than %{hard_min} per week given the household’s working situation." @@ -87,3 +88,5 @@ en: needstype: rent_below_hard_min: "Rent is below the absolute minimum expected for a property of this type based on this lettings type." rent_above_hard_max: "Rent is higher than the absolute maximum expected for a property of this type based on this lettings type." + hb: + housing_benefits_not_match_income_source: "You answered that none of the household’s income is from Universal Credit, state pensions or benefits, but also that the tenant is likely to be receiving Universal Credit or housing benefit." diff --git a/lib/tasks/update_logs_with_invalid_hb_benefits_2026.rake b/lib/tasks/update_logs_with_invalid_hb_benefits_2026.rake new file mode 100644 index 000000000..638d7d899 --- /dev/null +++ b/lib/tasks/update_logs_with_invalid_hb_benefits_2026.rake @@ -0,0 +1,10 @@ +desc "For logs that fail the validate_housing_universal_credit_matches_income_proportion check created before we released it, clear the answer to the question" +task update_logs_with_invalid_hb_benefits_2026: :environment do + impacted_logs = LettingsLog.filter_by_year(2026).where(hb: [1, 6], benefits: 3) + + puts "#{impacted_logs.count} logs will be updated #{impacted_logs.map(&:id)}" + + impacted_logs.update!(benefits: nil, hb: nil) + + puts "Done" +end diff --git a/spec/models/validations/financial_validations_spec.rb b/spec/models/validations/financial_validations_spec.rb index 14e2dfd0c..e4bdb2e82 100644 --- a/spec/models/validations/financial_validations_spec.rb +++ b/spec/models/validations/financial_validations_spec.rb @@ -5,11 +5,6 @@ RSpec.describe Validations::FinancialValidations do let(:validator_class) { Class.new { include Validations::FinancialValidations } } let(:record) { FactoryBot.create(:lettings_log) } - let(:fake_2021_2022_form) { Form.new("spec/fixtures/forms/2021_2022.json") } - - before do - allow(FormHandler.instance).to receive(:current_lettings_form).and_return(fake_2021_2022_form) - end describe "earnings and income frequency" do it "when earnings are provided it validates that income frequency must be provided" do @@ -1234,4 +1229,100 @@ RSpec.describe Validations::FinancialValidations do end end end + + describe "universal credit and income sources validations" do + before do + record.hb = hb + record.benefits = benefits + end + + context "with a 2025 form", metadata: { year: 25 } do + before do + allow(record.form).to receive(:start_year_2026_or_later?).and_return(false) + end + + context "when tenant receives universal credit and no household income comes from benefits" do + let(:hb) { 6 } + let(:benefits) { 3 } + + it "does not add errors" do + financial_validator.validate_housing_benefits_matches_income_proportion(record) + expect(record.errors["hb"]).to be_empty + expect(record.errors["benefits"]).to be_empty + end + end + end + + context "with a 2026 form", metadata: { year: 26 } do + before do + allow(record.form).to receive(:start_year_2026_or_later?).and_return(true) + end + + context "when tenant receives universal credit and no household income comes from benefits" do + let(:hb) { 6 } + let(:benefits) { 3 } + + it "adds errors to hb and benefits" do + financial_validator.validate_housing_benefits_matches_income_proportion(record) + expect(record.errors["hb"]).to include(match I18n.t("validations.lettings.financial.hb.housing_benefits_not_match_income_source")) + expect(record.errors["benefits"]).to include(match I18n.t("validations.lettings.financial.benefits.housing_benefits_not_match_income_source")) + end + end + + context "when tenant receives universal credit and some household income comes from benefits" do + let(:hb) { 6 } + let(:benefits) { 2 } + + it "does not add errors" do + financial_validator.validate_housing_benefits_matches_income_proportion(record) + expect(record.errors["hb"]).to be_empty + expect(record.errors["benefits"]).to be_empty + end + end + + context "when tenant receives housing benefit and no household income comes from benefits" do + let(:hb) { 1 } + let(:benefits) { 3 } + + it "adds errors to hb and benefits" do + financial_validator.validate_housing_benefits_matches_income_proportion(record) + expect(record.errors["hb"]).to include(match I18n.t("validations.lettings.financial.hb.housing_benefits_not_match_income_source")) + expect(record.errors["benefits"]).to include(match I18n.t("validations.lettings.financial.benefits.housing_benefits_not_match_income_source")) + end + end + + context "when tenant receives housing benefit and some household income comes from benefits" do + let(:hb) { 1 } + let(:benefits) { 2 } + + it "does not add errors" do + financial_validator.validate_housing_benefits_matches_income_proportion(record) + expect(record.errors["hb"]).to be_empty + expect(record.errors["benefits"]).to be_empty + end + end + + context "when hb is not set" do + let(:hb) { nil } + let(:benefits) { 3 } + + it "does not add errors" do + financial_validator.validate_housing_benefits_matches_income_proportion(record) + expect(record.errors["hb"]).to be_empty + expect(record.errors["benefits"]).to be_empty + end + end + + context "when benefits is not set" do + let(:hb) { 6 } + let(:benefits) { nil } + + it "does not add errors" do + financial_validator.validate_housing_benefits_matches_income_proportion(record) + expect(record.errors["hb"]).to be_empty + expect(record.errors["benefits"]).to be_empty + end + end + end + end end