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..82a5550f4 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_universal_credit_matches_income_proportion(record) + return unless record.hb && record.benefits && record.form.start_year_2026_or_later? + + if record.receives_universal_credit && record.no_household_income_comes_from_benefits? + record.errors.add :hb, I18n.t("validations.lettings.financial.hb.benefits_received_not_match_income_source") + record.errors.add :benefits, I18n.t("validations.lettings.financial.benefits.benefits_received_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..bc731d696 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." + benefits_received_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." 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: + benefits_received_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." 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..4770db96a --- /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: 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..358cbeaf1 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,89 @@ 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_universal_credit_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_universal_credit_matches_income_proportion(record) + expect(record.errors["hb"]).to include(match I18n.t("validations.lettings.financial.hb.benefits_received_not_match_income_source")) + expect(record.errors["benefits"]).to include(match I18n.t("validations.lettings.financial.benefits.benefits_received_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_universal_credit_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 "does not add errors" do + financial_validator.validate_housing_universal_credit_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_universal_credit_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_universal_credit_matches_income_proportion(record) + expect(record.errors["hb"]).to be_empty + expect(record.errors["benefits"]).to be_empty + end + end + end + end end