diff --git a/app/models/lettings_log.rb b/app/models/lettings_log.rb index 1b9b74bb8..8ebf8092f 100644 --- a/app/models/lettings_log.rb +++ b/app/models/lettings_log.rb @@ -213,28 +213,14 @@ class LettingsLog < Log format_as_currency((field_value * 52) / num_of_weeks) end - def all_relevant_ecstat_provided - return false unless ecstat1 - - if hhmemb && hhmemb > 1 - (2..hhmemb).each do |person_index| - next if details_not_known_for_person?(person_index) - - return false unless self["ecstat#{person_index}"] - end - end - - true - end - def applicable_income_range - return unless all_relevant_ecstat_provided + return unless ecstat1 && hhmemb range = ALLOWED_INCOME_RANGES[ecstat1].clone - if hhmemb && hhmemb > 1 + if hhmemb > 1 (2..hhmemb).each do |person_index| - ecstat = details_not_known_for_person?(person_index) ? 10 : self["ecstat#{person_index}"] + ecstat = self["ecstat#{person_index}"] || 10 person_range = ALLOWED_INCOME_RANGES[ecstat] range.soft_min += person_range.soft_min diff --git a/app/models/validations/financial_validations.rb b/app/models/validations/financial_validations.rb index defc4eedf..4da2201e7 100644 --- a/app/models/validations/financial_validations.rb +++ b/app/models/validations/financial_validations.rb @@ -24,15 +24,20 @@ module Validations::FinancialValidations end def validate_net_income(record) - if record.all_relevant_ecstat_provided && record.weekly_net_income + if record.ecstat1 && record.hhmemb && record.weekly_net_income + frequency = record.form.get_question("incfreq", record).label_from_value(record.incfreq).downcase if record.weekly_net_income > record.applicable_income_range.hard_max hard_max = format_as_currency(record.applicable_income_range.hard_max) - frequency = record.form.get_question("incfreq", record).label_from_value(record.incfreq).downcase record.errors.add( :earnings, :over_hard_max, message: I18n.t("validations.financial.earnings.over_hard_max", hard_max:), ) + record.errors.add( + :hhmemb, + :over_hard_max, + message: I18n.t("validations.financial.hhmemb.earnings.over_hard_max", earnings: format_as_currency(record.earnings), frequency:), + ) ecstat_fields = %i[ecstat1 ecstat2 ecstat3 ecstat4 ecstat5 ecstat6 ecstat7 ecstat8] ecstat_fields.each do |field| record.errors.add( @@ -47,7 +52,7 @@ module Validations::FinancialValidations record.errors.add( "age#{n}", :over_hard_max, - message: I18n.t("validations.financial.ecstat.inferred_child.over_hard_max", earnings: format_as_currency(record.earnings), frequency:), + message: I18n.t("validations.financial.age.earnings_over_hard_max", earnings: format_as_currency(record.earnings), frequency:), ) end end @@ -59,6 +64,20 @@ module Validations::FinancialValidations :under_hard_min, message: I18n.t("validations.financial.earnings.under_hard_min", hard_min:), ) + record.errors.add( + :hhmemb, + :under_hard_min, + message: I18n.t("validations.financial.hhmemb.earnings.under_hard_min", earnings: format_as_currency(record.earnings), frequency:), + ) + ecstat_fields = %i[ecstat1 ecstat2 ecstat3 ecstat4 ecstat5 ecstat6 ecstat7 ecstat8] + ecstat_fields.each do |field| + record.errors.add( + field, + :under_hard_min, + message: I18n.t("validations.financial.ecstat.under_hard_min", earnings: format_as_currency(record.earnings), frequency:), + ) + end + # N.B. It is not possible for a change to an age field to increase the hard min end end diff --git a/app/models/validations/soft_validations.rb b/app/models/validations/soft_validations.rb index 7c4f5c65d..92685afe0 100644 --- a/app/models/validations/soft_validations.rb +++ b/app/models/validations/soft_validations.rb @@ -14,13 +14,13 @@ module Validations::SoftValidations }.freeze def net_income_in_soft_max_range? - return unless weekly_net_income && all_relevant_ecstat_provided + return unless weekly_net_income && ecstat1 && hhmemb 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 && all_relevant_ecstat_provided + return unless weekly_net_income && ecstat1 && hhmemb weekly_net_income.between?(applicable_income_range.hard_min, applicable_income_range.soft_min) end diff --git a/config/locales/en.yml b/config/locales/en.yml index 5b35aaae8..7e8720cf0 100644 --- a/config/locales/en.yml +++ b/config/locales/en.yml @@ -377,8 +377,13 @@ en: out_of_range: "Enter a value for the %{charge_name} between £0 and %{maximum_per_period} paid %{frequency}. %{maximum_per_period} is the max limit for rent and charges paid %{frequency} for %{letting_type} lettings owned by a %{provider_type}." ecstat: over_hard_max: "The household's income of %{earnings} %{frequency} is too high given the household’s working situation" - inferred_child: - over_hard_max: "The household's income of %{earnings} %{frequency} is too high given the household’s characteristics and working situation" + under_hard_min: "The household's income of %{earnings} %{frequency} is too low given the household’s working situation" + age: + earnings_over_hard_max: "The household's income of %{earnings} %{frequency} is too high for the number of adults. Change either the household income or the age of the tenants." + hhmemb: + earnings: + over_hard_max: "The household's income of %{earnings} %{frequency} is too high for this number of tenants. Change either the household income or number of tenants." + under_hard_min: "The household's income of %{earnings} %{frequency} is too low for this number of tenants. Change either the household income or number of tenants." brent: below_hard_min: "Rent is below the absolute minimum expected for a property of this type. Please check the rent, rent period, local authority and (if general needs) number of bedrooms" above_hard_max: "Rent is higher than the absolute maximum expected for a property of this type. Please check the rent, rent period, local authority and (if general needs) number of bedrooms" diff --git a/spec/features/form/validations_spec.rb b/spec/features/form/validations_spec.rb index 561f31c8d..497897f8d 100644 --- a/spec/features/form/validations_spec.rb +++ b/spec/features/form/validations_spec.rb @@ -131,6 +131,7 @@ RSpec.describe "validations" do FactoryBot.create( :lettings_log, :in_progress, + hhmemb: 1, ecstat1: 1, created_by: user, ) diff --git a/spec/models/lettings_log_spec.rb b/spec/models/lettings_log_spec.rb index 6a5ba1477..1b641f452 100644 --- a/spec/models/lettings_log_spec.rb +++ b/spec/models/lettings_log_spec.rb @@ -3412,30 +3412,34 @@ RSpec.describe LettingsLog do end end - describe "#all_relevant_ecstat_provided" do - context "when details for a non-lead tenant are not known" do - let(:lettings_log) { build(:lettings_log, hhmemb: 2, ecstat1: 1, details_known_2: 1) } - - it "returns true" do - expect(lettings_log.all_relevant_ecstat_provided).to be(true) + describe "#applicable_income_range" do + context "when ecstat for a non-lead tenant is not set" do + let(:lettings_log) { build(:lettings_log, hhmemb: 2, ecstat1: 1) } + + it "uses the prefers-not-to-say values for that tenant to calculate the range" do + range = lettings_log.applicable_income_range + expected_range = OpenStruct.new( + soft_min: 143 + 47, + soft_max: 730 + 730, + hard_min: 90 + 10, + hard_max: 1230 + 2000, + ) + expect(range).to eq(expected_range) end end - context "when details for a non-lead tenant are known" do - context "and that person's ecstat is provided" do - let(:lettings_log) { build(:lettings_log, hhmemb: 2, ecstat1: 1, details_known_2: 0, ecstat2: 2) } + context "when ecstat for a non-lead tenant is set" do + let(:lettings_log) { build(:lettings_log, hhmemb: 2, ecstat1: 1, ecstat2: 2) } - it "returns true" do - expect(lettings_log.all_relevant_ecstat_provided).to be(true) - end - end - - context "and that person's ecstat is not provided" do - let(:lettings_log) { build(:lettings_log, hhmemb: 2, ecstat1: 1, details_known_2: 0) } - - it "returns true" do - expect(lettings_log.all_relevant_ecstat_provided).to be(false) - end + it "uses the relevant income range values for that tenant to calculate the range" do + range = lettings_log.applicable_income_range + expected_range = OpenStruct.new( + soft_min: 143 + 67, + soft_max: 730 + 620, + hard_min: 90 + 50, + hard_max: 1230 + 950, + ) + expect(range).to eq(expected_range) end end end diff --git a/spec/models/validations/financial_validations_spec.rb b/spec/models/validations/financial_validations_spec.rb index 49a1c8de7..3b3d70546 100644 --- a/spec/models/validations/financial_validations_spec.rb +++ b/spec/models/validations/financial_validations_spec.rb @@ -190,6 +190,7 @@ RSpec.describe Validations::FinancialValidations do it "validates that the net income is within the expected range for the household’s employment status" do record.earnings = 200 record.incfreq = 1 + record.hhmemb = 1 record.ecstat1 = 1 financial_validator.validate_net_income(record) expect(record.errors["earnings"]).to be_empty @@ -199,12 +200,15 @@ RSpec.describe Validations::FinancialValidations do it "adds an error" do record.earnings = 5000 record.incfreq = 1 + record.hhmemb = 1 record.ecstat1 = 1 financial_validator.validate_net_income(record) expect(record.errors["earnings"]) .to eq(["The household's income cannot be greater than £1,230.00 per week given the household’s working situation"]) expect(record.errors["ecstat1"]) .to eq(["The household's income of £5,000.00 weekly is too high given the household’s working situation"]) + expect(record.errors["hhmemb"]) + .to eq(["The household's income of £5,000.00 weekly is too high for this number of tenants. Change either the household income or number of tenants."]) end end @@ -212,10 +216,15 @@ RSpec.describe Validations::FinancialValidations do it "adds an error" do record.earnings = 50 record.incfreq = 1 + record.hhmemb = 1 record.ecstat1 = 1 financial_validator.validate_net_income(record) expect(record.errors["earnings"]) .to eq(["The household's income cannot be less than £90.00 per week given the household’s working situation"]) + expect(record.errors["ecstat1"]) + .to eq(["The household's income of £50.00 weekly is too low given the household’s working situation"]) + expect(record.errors["hhmemb"]) + .to eq(["The household's income of £50.00 weekly is too low for this number of tenants. Change either the household income or number of tenants."]) end end @@ -260,7 +269,22 @@ RSpec.describe Validations::FinancialValidations do expect(record.errors["age1"]).to be_empty expect(record.errors["age2"]).to be_empty expect(record.errors["age3"]) - .to eq(["The household's income of £5,000.00 weekly is too high given the household’s characteristics and working situation"]) + .to eq(["The household's income of £5,000.00 weekly is too high for the number of adults. Change either the household income or the age of the tenants."]) + end + + it "adds errors to relevant fields for each tenant when income is too low" do + record.earnings = 50 + record.incfreq = 1 + record.hhmemb = 3 + record.ecstat1 = 1 + record.ecstat2 = 2 + record.age3 = 12 + record.ecstat3 = 9 + financial_validator.validate_net_income(record) + (1..record.hhmemb).each do |n| + expect(record.errors["ecstat#{n}"]) + .to eq(["The household's income of £50.00 weekly is too low given the household’s working situation"]) + end end end end