Browse Source

CLDC-2272 Fix UPRN income validation bug (#1553)

* feat: add hard income validations to uprn question

* feat: fix typo

* db:update

* feat: update tests
pull/1582/head
natdeanlewissoftwire 2 years ago committed by GitHub
parent
commit
b816968104
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
  1. 2
      app/models/form/lettings/questions/uprn.rb
  2. 2
      app/models/form/sales/questions/uprn.rb
  3. 4
      app/models/lettings_log.rb
  4. 4
      app/models/sales_log.rb
  5. 2
      app/models/validations/financial_validations.rb
  6. 6
      app/models/validations/sales/financial_validations.rb
  7. 3
      config/locales/en.yml
  8. 2
      spec/fixtures/exports/general_needs_log_23_24.xml
  9. 2
      spec/models/form/lettings/questions/uprn_spec.rb
  10. 2
      spec/models/form/sales/questions/uprn_spec.rb
  11. 5
      spec/services/exports/lettings_log_export_service_spec.rb

2
app/models/form/lettings/questions/uprn.rb

@ -3,7 +3,7 @@ class Form::Lettings::Questions::Uprn < ::Form::Question
super super
@id = "uprn" @id = "uprn"
@check_answer_label = "UPRN" @check_answer_label = "UPRN"
@header = "What is the property's UPRN" @header = "What is the property's UPRN?"
@type = "text" @type = "text"
@width = 10 @width = 10
@question_number = 11 @question_number = 11

2
app/models/form/sales/questions/uprn.rb

@ -3,7 +3,7 @@ class Form::Sales::Questions::Uprn < ::Form::Question
super super
@id = "uprn" @id = "uprn"
@check_answer_label = "UPRN" @check_answer_label = "UPRN"
@header = "What is the property's UPRN" @header = "What is the property's UPRN?"
@type = "text" @type = "text"
@width = 10 @width = 10
@question_number = 14 @question_number = 14

4
app/models/lettings_log.rb

@ -33,7 +33,7 @@ class LettingsLog < Log
before_validation :reset_location_fields!, unless: :postcode_known? before_validation :reset_location_fields!, unless: :postcode_known?
before_validation :reset_previous_location_fields!, unless: :previous_postcode_known? before_validation :reset_previous_location_fields!, unless: :previous_postcode_known?
before_validation :set_derived_fields! before_validation :set_derived_fields!
after_validation :process_uprn_change!, if: :should_process_uprn_change? before_validation :process_uprn_change!, if: :should_process_uprn_change?
belongs_to :scheme, optional: true belongs_to :scheme, optional: true
belongs_to :location, optional: true belongs_to :location, optional: true
@ -701,6 +701,6 @@ private
end end
def should_process_uprn_change? def should_process_uprn_change?
uprn_changed? && startdate && startdate.year >= 2023 uprn && startdate && (uprn_changed? || startdate_changed?) && startdate.year >= 2023
end end
end end

4
app/models/sales_log.rb

@ -32,7 +32,7 @@ class SalesLog < Log
before_validation :reset_location_fields!, unless: :postcode_known? before_validation :reset_location_fields!, unless: :postcode_known?
before_validation :reset_previous_location_fields!, unless: :previous_postcode_known? before_validation :reset_previous_location_fields!, unless: :previous_postcode_known?
before_validation :set_derived_fields! before_validation :set_derived_fields!
after_validation :process_uprn_change!, if: :should_process_uprn_change? before_validation :process_uprn_change!, if: :should_process_uprn_change?
scope :filter_by_year, ->(year) { where(saledate: Time.zone.local(year.to_i, 4, 1)...Time.zone.local(year.to_i + 1, 4, 1)) } scope :filter_by_year, ->(year) { where(saledate: Time.zone.local(year.to_i, 4, 1)...Time.zone.local(year.to_i + 1, 4, 1)) }
scope :filter_by_purchaser_code, ->(purchid) { where("purchid ILIKE ?", "%#{purchid}%") } scope :filter_by_purchaser_code, ->(purchid) { where("purchid ILIKE ?", "%#{purchid}%") }
@ -328,7 +328,7 @@ class SalesLog < Log
end end
def should_process_uprn_change? def should_process_uprn_change?
uprn_changed? && saledate && saledate.year >= 2023 uprn && saledate && (uprn_changed? || saledate_changed?) && saledate.year >= 2023
end end
def value_with_discount def value_with_discount

2
app/models/validations/financial_validations.rb

@ -214,6 +214,7 @@ private
if record.weekly_value(record["brent"]) < rent_range.hard_min if record.weekly_value(record["brent"]) < rent_range.hard_min
record.errors.add :brent, I18n.t("validations.financial.brent.below_hard_min") record.errors.add :brent, I18n.t("validations.financial.brent.below_hard_min")
record.errors.add :beds, I18n.t("validations.financial.brent.beds.below_hard_min") record.errors.add :beds, I18n.t("validations.financial.brent.beds.below_hard_min")
record.errors.add :uprn, I18n.t("validations.financial.brent.uprn.below_hard_min")
record.errors.add :la, I18n.t("validations.financial.brent.la.below_hard_min") record.errors.add :la, I18n.t("validations.financial.brent.la.below_hard_min")
record.errors.add :postcode_known, I18n.t("validations.financial.brent.postcode_known.below_hard_min") record.errors.add :postcode_known, I18n.t("validations.financial.brent.postcode_known.below_hard_min")
record.errors.add :scheme_id, I18n.t("validations.financial.brent.scheme_id.below_hard_min") record.errors.add :scheme_id, I18n.t("validations.financial.brent.scheme_id.below_hard_min")
@ -226,6 +227,7 @@ private
if record.weekly_value(record["brent"]) > rent_range.hard_max if record.weekly_value(record["brent"]) > rent_range.hard_max
record.errors.add :brent, :over_hard_max, message: I18n.t("validations.financial.brent.above_hard_max") record.errors.add :brent, :over_hard_max, message: I18n.t("validations.financial.brent.above_hard_max")
record.errors.add :beds, I18n.t("validations.financial.brent.beds.above_hard_max") record.errors.add :beds, I18n.t("validations.financial.brent.beds.above_hard_max")
record.errors.add :uprn, I18n.t("validations.financial.brent.uprn.above_hard_max")
record.errors.add :la, I18n.t("validations.financial.brent.la.above_hard_max") record.errors.add :la, I18n.t("validations.financial.brent.la.above_hard_max")
record.errors.add :postcode_known, I18n.t("validations.financial.brent.postcode_known.above_hard_max") record.errors.add :postcode_known, I18n.t("validations.financial.brent.postcode_known.above_hard_max")
record.errors.add :scheme_id, I18n.t("validations.financial.brent.scheme_id.above_hard_max") record.errors.add :scheme_id, I18n.t("validations.financial.brent.scheme_id.above_hard_max")

6
app/models/validations/sales/financial_validations.rb

@ -5,7 +5,7 @@ module Validations::Sales::FinancialValidations
def validate_income1(record) def validate_income1(record)
return unless record.income1 && record.la && record.shared_ownership_scheme? return unless record.income1 && record.la && record.shared_ownership_scheme?
relevant_fields = %i[income1 ownershipsch la postcode_full] relevant_fields = %i[income1 ownershipsch uprn la postcode_full]
if record.london_property? && record.income1 > 90_000 if record.london_property? && record.income1 > 90_000
relevant_fields.each { |field| record.errors.add field, I18n.t("validations.financial.income.over_hard_max_for_london") } relevant_fields.each { |field| record.errors.add field, I18n.t("validations.financial.income.over_hard_max_for_london") }
elsif record.property_not_in_london? && record.income1 > 80_000 elsif record.property_not_in_london? && record.income1 > 80_000
@ -16,7 +16,7 @@ module Validations::Sales::FinancialValidations
def validate_income2(record) def validate_income2(record)
return unless record.income2 && record.la && record.shared_ownership_scheme? return unless record.income2 && record.la && record.shared_ownership_scheme?
relevant_fields = %i[income2 ownershipsch la postcode_full] relevant_fields = %i[income2 ownershipsch uprn la postcode_full]
if record.london_property? && record.income2 > 90_000 if record.london_property? && record.income2 > 90_000
relevant_fields.each { |field| record.errors.add field, I18n.t("validations.financial.income.over_hard_max_for_london") } relevant_fields.each { |field| record.errors.add field, I18n.t("validations.financial.income.over_hard_max_for_london") }
elsif record.property_not_in_london? && record.income2 > 80_000 elsif record.property_not_in_london? && record.income2 > 80_000
@ -28,7 +28,7 @@ module Validations::Sales::FinancialValidations
return unless record.income1 && record.income2 && record.la && record.shared_ownership_scheme? return unless record.income1 && record.income2 && record.la && record.shared_ownership_scheme?
combined_income = record.income1 + record.income2 combined_income = record.income1 + record.income2
relevant_fields = %i[income1 income2 ownershipsch la postcode_full] relevant_fields = %i[income1 income2 ownershipsch uprn la postcode_full]
if record.london_property? && combined_income > 90_000 if record.london_property? && combined_income > 90_000
relevant_fields.each { |field| record.errors.add field, I18n.t("validations.financial.income.combined_over_hard_max_for_london") } relevant_fields.each { |field| record.errors.add field, I18n.t("validations.financial.income.combined_over_hard_max_for_london") }
elsif record.property_not_in_london? && combined_income > 80_000 elsif record.property_not_in_london? && combined_income > 80_000

3
config/locales/en.yml

@ -297,6 +297,9 @@ en:
postcode_known: postcode_known:
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 number of bedrooms" 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 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 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 number of bedrooms"
uprn:
below_hard_min: "Rent is below the absolute minimum expected for a property of this type based on this UPRN"
above_hard_max: "Rent is higher than the absolute maximum expected for a property of this type based on this UPRN"
la: la:
below_hard_min: "Rent is below the absolute minimum expected for a property of this type based on this local authority" below_hard_min: "Rent is below the absolute minimum expected for a property of this type based on this local authority"
above_hard_max: "Rent is higher than the absolute maximum expected for a property of this type based on this local authority" above_hard_max: "Rent is higher than the absolute maximum expected for a property of this type based on this local authority"

2
spec/fixtures/exports/general_needs_log_23_24.xml vendored

@ -52,7 +52,7 @@
<period>2</period> <period>2</period>
<layear>2</layear> <layear>2</layear>
<waityear>7</waityear> <waityear>7</waityear>
<postcode_full/> <postcode_full>SE2 6RT</postcode_full>
<reasonpref>1</reasonpref> <reasonpref>1</reasonpref>
<cbl>2</cbl> <cbl>2</cbl>
<chr>1</chr> <chr>1</chr>

2
spec/models/form/lettings/questions/uprn_spec.rb

@ -16,7 +16,7 @@ RSpec.describe Form::Lettings::Questions::Uprn, type: :model do
end end
it "has the correct header" do it "has the correct header" do
expect(question.header).to eq("What is the property's UPRN") expect(question.header).to eq("What is the property's UPRN?")
end end
it "has the correct check_answer_label" do it "has the correct check_answer_label" do

2
spec/models/form/sales/questions/uprn_spec.rb

@ -16,7 +16,7 @@ RSpec.describe Form::Sales::Questions::Uprn, type: :model do
end end
it "has the correct header" do it "has the correct header" do
expect(question.header).to eq("What is the property's UPRN") expect(question.header).to eq("What is the property's UPRN?")
end end
it "has the correct check_answer_label" do it "has the correct check_answer_label" do

5
spec/services/exports/lettings_log_export_service_spec.rb

@ -160,7 +160,8 @@ RSpec.describe Exports::LettingsLogExportService do
"BUILDING_NUMBER": "number", "BUILDING_NUMBER": "number",
"DEPENDENT_THOROUGHFARE_NAME": "data", "DEPENDENT_THOROUGHFARE_NAME": "data",
"THOROUGHFARE_NAME": "thing", "THOROUGHFARE_NAME": "thing",
"POST_TOWN": "London" "POST_TOWN": "London",
"POSTCODE": "SE2 6RT"
}}]}', headers: {}) }}]}', headers: {})
end end
@ -171,7 +172,7 @@ RSpec.describe Exports::LettingsLogExportService do
end end
context "and one lettings log is available for export" do context "and one lettings log is available for export" do
let!(:lettings_log) { FactoryBot.create(:lettings_log, :completed, uprn_known: 1, uprn: "100023336956", propcode: "123", ppostcode_full: "SE2 6RT", tenancycode: "BZ737", startdate: Time.zone.local(2023, 4, 2, 10, 36, 49), voiddate: Time.zone.local(2021, 11, 3), mrcdate: Time.zone.local(2022, 5, 5, 10, 36, 49), tenancylength: 5, underoccupation_benefitcap: 4) } let!(:lettings_log) { FactoryBot.create(:lettings_log, :completed, uprn_known: 1, uprn: "100023336956", propcode: "123", postcode_full: "SE2 6RT", ppostcode_full: "SE2 6RT", tenancycode: "BZ737", startdate: Time.zone.local(2023, 4, 2, 10, 36, 49), voiddate: Time.zone.local(2021, 11, 3), mrcdate: Time.zone.local(2022, 5, 5, 10, 36, 49), tenancylength: 5, underoccupation_benefitcap: 4) }
let(:expected_zip_filename) { "core_2023_2024_apr_mar_f0001_inc0001.zip" } let(:expected_zip_filename) { "core_2023_2024_apr_mar_f0001_inc0001.zip" }
let(:expected_data_filename) { "core_2023_2024_apr_mar_f0001_inc0001_pt001.xml" } let(:expected_data_filename) { "core_2023_2024_apr_mar_f0001_inc0001_pt001.xml" }
let(:xml_export_file) { File.open("spec/fixtures/exports/general_needs_log_23_24.xml", "r:UTF-8") } let(:xml_export_file) { File.open("spec/fixtures/exports/general_needs_log_23_24.xml", "r:UTF-8") }

Loading…
Cancel
Save