Browse Source

CLDC-2163 add validations on whether buyers are living in the property (#1512)

* add several methods to the sales log to allow subsequent work to be human readable

* add a validation to prevent an inconsistent combination of values and tests for this validation

* handle derivation of values around buyers living in the property
- derive values where appropriate
- clear these values when the derived state no longer holds
- update the routing for pages holding questions about whether particular buyers will live in the property to reflect when they are derived
- test the deriving and associated clearing of values
- update tests on page routing and sales log factory

* update a page routing condition for human readability using an existing method and update test to reflect this change

* show related method in diff

* minor amendments after tech review

* simplify reset_derived_questions after tech review

* refactor on deriving and clearing invalid derived values on sales log

* correct linter complaints

* remove comment

* add validation to one more field with a new error message as it is in fact possible to tirgger the validation in the setup section
pull/1599/head
Arthur Campbell 2 years ago committed by GitHub
parent
commit
899c9995d9
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
  1. 69
      app/models/derived_variables/sales_log_variables.rb
  2. 12
      app/models/form/sales/pages/buyer1_live_in_property.rb
  3. 14
      app/models/form/sales/pages/buyer2_live_in_property.rb
  4. 2
      app/models/form/sales/pages/buyer_company.rb
  5. 26
      app/models/sales_log.rb
  6. 10
      app/models/validations/sales/household_validations.rb
  7. 3
      config/locales/en.yml
  8. 21
      spec/models/form/sales/pages/buyer1_live_in_property_spec.rb
  9. 14
      spec/models/form/sales/pages/buyer2_live_in_property_spec.rb
  10. 4
      spec/models/form/sales/pages/buyer_company_spec.rb
  11. 64
      spec/models/sales_log_spec.rb
  12. 57
      spec/models/validations/sales/household_validations_spec.rb

69
app/models/derived_variables/sales_log_variables.rb

@ -1,5 +1,7 @@
module DerivedVariables::SalesLogVariables module DerivedVariables::SalesLogVariables
def set_derived_fields! def set_derived_fields!
reset_invalidated_derived_values!
self.ethnic = 17 if ethnic_refused? self.ethnic = 17 if ethnic_refused?
self.mscharge = nil if no_monthly_leasehold_charges? self.mscharge = nil if no_monthly_leasehold_charges?
if exdate.present? if exdate.present?
@ -13,9 +15,6 @@ module DerivedVariables::SalesLogVariables
self.hoyear = hodate.year self.hoyear = hodate.year
end end
self.deposit = value if outright_sale? && mortgage_not_used? self.deposit = value if outright_sale? && mortgage_not_used?
if mortgage_not_used?
self.mortgage = 0
end
self.pcode1, self.pcode2 = postcode_full.split(" ") if postcode_full.present? self.pcode1, self.pcode2 = postcode_full.split(" ") if postcode_full.present?
self.totchild = total_child self.totchild = total_child
self.totadult = total_adult + total_elder self.totadult = total_adult + total_elder
@ -30,10 +29,74 @@ module DerivedVariables::SalesLogVariables
self.uprn = nil self.uprn = nil
self.uprn_known = 0 self.uprn_known = 0
end end
set_encoded_derived_values!
end end
private private
DEPENDENCIES = [
{
conditions: {
buylivein: 2,
},
derived_values: {
buy1livein: 2,
},
},
{
conditions: {
buylivein: 2,
jointpur: 1,
},
derived_values: {
buy1livein: 2,
buy2livein: 2,
},
},
{
conditions: {
buylivein: 1,
jointpur: 2,
},
derived_values: {
buy1livein: 1,
},
},
{
conditions: {
mortgageused: 2,
},
derived_values: {
mortgage: 0,
},
},
].freeze
def reset_invalidated_derived_values!
DEPENDENCIES.each do |dependency|
any_conditions_changed = dependency[:conditions].any? { |attribute, _value| send("#{attribute}_changed?") }
next unless any_conditions_changed
previously_in_derived_state = dependency[:conditions].all? { |attribute, value| send("#{attribute}_was") == value }
next unless previously_in_derived_state
dependency[:derived_values].each do |derived_attribute, _derived_value|
Rails.logger.debug("Cleared derived #{derived_attribute} value")
send("#{derived_attribute}=", nil)
end
end
end
def set_encoded_derived_values!
DEPENDENCIES.each do |dependency|
derivation_applies = dependency[:conditions].all? { |attribute, value| send(attribute) == value }
if derivation_applies
dependency[:derived_values].each { |attribute, value| send("#{attribute}=", value) }
end
end
end
def number_of_household_members def number_of_household_members
return unless hholdcount.present? && jointpur.present? return unless hholdcount.present? && jointpur.present?

12
app/models/form/sales/pages/buyer1_live_in_property.rb

@ -5,9 +5,21 @@ class Form::Sales::Pages::Buyer1LiveInProperty < ::Form::Page
@depends_on = [ @depends_on = [
{ {
"buyer_has_seen_privacy_notice?" => true, "buyer_has_seen_privacy_notice?" => true,
"outright_sale?" => false,
}, },
{ {
"buyer_not_interviewed?" => true, "buyer_not_interviewed?" => true,
"outright_sale?" => false,
},
{
"buyer_has_seen_privacy_notice?" => true,
"joint_purchase?" => true,
"buyers_will_live_in?" => true,
},
{
"buyer_not_interviewed?" => true,
"joint_purchase?" => true,
"buyers_will_live_in?" => true,
}, },
] ]
end end

14
app/models/form/sales/pages/buyer2_live_in_property.rb

@ -4,12 +4,24 @@ class Form::Sales::Pages::Buyer2LiveInProperty < ::Form::Page
@id = "buyer_2_live_in_property" @id = "buyer_2_live_in_property"
@depends_on = [ @depends_on = [
{ {
"joint_purchase?" => true,
"buyer_has_seen_privacy_notice?" => true, "buyer_has_seen_privacy_notice?" => true,
"outright_sale?" => false,
"joint_purchase?" => true,
},
{
"buyer_not_interviewed?" => true,
"outright_sale?" => false,
"joint_purchase?" => true,
}, },
{ {
"buyer_has_seen_privacy_notice?" => true,
"joint_purchase?" => true, "joint_purchase?" => true,
"buyers_will_live_in?" => true,
},
{
"buyer_not_interviewed?" => true, "buyer_not_interviewed?" => true,
"joint_purchase?" => true,
"buyers_will_live_in?" => true,
}, },
] ]
end end

2
app/models/form/sales/pages/buyer_company.rb

@ -3,7 +3,7 @@ class Form::Sales::Pages::BuyerCompany < ::Form::Page
super super
@id = "buyer_company" @id = "buyer_company"
@depends_on = [{ @depends_on = [{
"ownershipsch" => 3, "outright_sale?" => true,
}] }]
end end

26
app/models/sales_log.rb

@ -26,7 +26,6 @@ class SalesLog < Log
validates_with SalesLogValidator validates_with SalesLogValidator
before_validation :recalculate_start_year!, if: :saledate_changed? before_validation :recalculate_start_year!, if: :saledate_changed?
before_validation :reset_invalidated_dependent_fields!
before_validation :process_postcode_changes!, if: :postcode_full_changed? before_validation :process_postcode_changes!, if: :postcode_full_changed?
before_validation :process_previous_postcode_changes!, if: :ppostcode_full_changed? before_validation :process_previous_postcode_changes!, if: :ppostcode_full_changed?
before_validation :reset_location_fields!, unless: :postcode_known? before_validation :reset_location_fields!, unless: :postcode_known?
@ -161,10 +160,26 @@ class SalesLog < Log
inc1mort == 1 inc1mort == 1
end end
def buyers_will_live_in?
buylivein == 1
end
def buyers_will_not_live_in?
buylivein == 2
end
def buyer_two_will_live_in_property? def buyer_two_will_live_in_property?
buy2livein == 1 buy2livein == 1
end end
def buyer_two_will_not_live_in_property?
buy2livein == 2
end
def buyer_one_will_not_live_in_property?
buy1livein == 2
end
def buyer_two_not_already_living_in_property? def buyer_two_not_already_living_in_property?
buy2living == 2 buy2living == 2
end end
@ -352,12 +367,9 @@ class SalesLog < Log
def ownership_scheme def ownership_scheme
case ownershipsch case ownershipsch
when 1 when 1 then "shared ownership"
"shared ownership" when 2 then "discounted ownership"
when 2 when 3 then "outright sale"
"discounted ownership"
when 3
"outright sale"
end end
end end
end end

10
app/models/validations/sales/household_validations.rb

@ -20,6 +20,16 @@ module Validations::Sales::HouseholdValidations
end end
end 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.household.buylivein.buyers_will_live_in_property_values_inconsistent_setup")
record.errors.add :buy1livein, I18n.t("validations.household.buylivein.buyers_will_live_in_property_values_inconsistent")
record.errors.add :buy2livein, I18n.t("validations.household.buylivein.buyers_will_live_in_property_values_inconsistent")
end
end
private private
def validate_person_age_matches_relationship(record, person_num) def validate_person_age_matches_relationship(record, person_num)

3
config/locales/en.yml

@ -442,6 +442,9 @@ en:
no_choices: "You cannot answer this question as you told us nobody in the household has a physical or mental health condition (or other illness) expected to last 12 months or more" no_choices: "You cannot answer this question as you told us nobody in the household has a physical or mental health condition (or other illness) expected to last 12 months or more"
postcode: postcode:
discounted_ownership: "Last settled accommodation and discounted ownership property postcodes must match" discounted_ownership: "Last settled accommodation and discounted ownership property postcodes must match"
buylivein:
buyers_will_live_in_property_values_inconsistent_setup: "You have already told us that both buyer 1 and buyer 2 will not live in the property"
buyers_will_live_in_property_values_inconsistent: "You have already told us that the buyers will live in the property. Either buyer 1 or buyer 2 must live in the property"
tenancy: tenancy:
length: length:

21
spec/models/form/sales/pages/buyer1_live_in_property_spec.rb

@ -28,6 +28,25 @@ RSpec.describe Form::Sales::Pages::Buyer1LiveInProperty, type: :model do
end end
it "has correct depends_on" do it "has correct depends_on" do
expect(page.depends_on).to eq([{ "buyer_has_seen_privacy_notice?" => true }, { "buyer_not_interviewed?" => true }]) expect(page.depends_on).to eq([
{
"buyer_has_seen_privacy_notice?" => true,
"outright_sale?" => false,
},
{
"buyer_not_interviewed?" => true,
"outright_sale?" => false,
},
{
"buyer_has_seen_privacy_notice?" => true,
"joint_purchase?" => true,
"buyers_will_live_in?" => true,
},
{
"buyer_not_interviewed?" => true,
"joint_purchase?" => true,
"buyers_will_live_in?" => true,
},
])
end end
end end

14
spec/models/form/sales/pages/buyer2_live_in_property_spec.rb

@ -30,12 +30,24 @@ RSpec.describe Form::Sales::Pages::Buyer2LiveInProperty, type: :model do
it "has correct depends_on" do it "has correct depends_on" do
expect(page.depends_on).to eq([ expect(page.depends_on).to eq([
{ {
"joint_purchase?" => true,
"buyer_has_seen_privacy_notice?" => true, "buyer_has_seen_privacy_notice?" => true,
"outright_sale?" => false,
"joint_purchase?" => true,
},
{
"buyer_not_interviewed?" => true,
"outright_sale?" => false,
"joint_purchase?" => true,
}, },
{ {
"buyer_has_seen_privacy_notice?" => true,
"joint_purchase?" => true, "joint_purchase?" => true,
"buyers_will_live_in?" => true,
},
{
"buyer_not_interviewed?" => true, "buyer_not_interviewed?" => true,
"joint_purchase?" => true,
"buyers_will_live_in?" => true,
}, },
]) ])
end end

4
spec/models/form/sales/pages/buyer_company_spec.rb

@ -28,8 +28,6 @@ RSpec.describe Form::Sales::Pages::BuyerCompany, type: :model do
end end
it "has correct depends_on" do it "has correct depends_on" do
expect(page.depends_on).to eq([{ expect(page.depends_on).to eq([{ "outright_sale?" => true }])
"ownershipsch" => 3,
}])
end end
end end

64
spec/models/sales_log_spec.rb

@ -220,6 +220,70 @@ RSpec.describe SalesLog, type: :model do
record_from_db = ActiveRecord::Base.connection.execute("select mortgage from sales_logs where id=#{sales_log.id}").to_a[0] record_from_db = ActiveRecord::Base.connection.execute("select mortgage from sales_logs where id=#{sales_log.id}").to_a[0]
expect(record_from_db["mortgage"]).to eq(0.0) expect(record_from_db["mortgage"]).to eq(0.0)
end end
it "clears mortgage value if mortgage used is changed from no to yes" do
# to avoid log failing validations when mortgage value is removed:
new_grant_value = sales_log.grant + sales_log.mortgage
sales_log.update!(mortgageused: 2, grant: new_grant_value)
sales_log.update!(mortgageused: 1)
record_from_db = ActiveRecord::Base.connection.execute("select mortgage from sales_logs where id=#{sales_log.id}").to_a[0]
expect(record_from_db["mortgage"]).to eq(nil)
end
context "when outright sale and buyers will live in the property" do
let(:sales_log) { create(:sales_log, :outright_sale_setup_complete, buylivein: 1, jointpur:) }
context "and the sale is not a joint purchase" do
let(:jointpur) { 2 }
it "derives that buyer 1 will live in the property" do
expect(sales_log.buy1livein).to be 1
end
it "does not derive a value for whether buyer 2 will live in the property" do
expect(sales_log.buy2livein).to be nil
end
it "clears that buyer 1 will live in the property if joint purchase is updated" do
sales_log.update!(jointpur: 1)
expect(sales_log.buy1livein).to be nil
end
end
context "and the sale is a joint purchase" do
let(:jointpur) { 1 }
it "does not derive values for whether buyer 1 or buyer 2 will live in the property" do
expect(sales_log.buy1livein).to be nil
expect(sales_log.buy2livein).to be nil
end
end
end
context "when outright sale and buyers will not live in the property" do
let(:sales_log) { create(:sales_log, :outright_sale_setup_complete, buylivein: 2, jointpur:) }
context "and the sale is not a joint purchase" do
let(:jointpur) { 2 }
it "derives that buyer 1 will not live in the property" do
expect(sales_log.buy1livein).to be 2
end
it "does not derive a value for whether buyer 2 will live in the property" do
expect(sales_log.buy2livein).to be nil
end
end
context "and the sale is a joint purchase" do
let(:jointpur) { 1 }
it "derives that neither buyer 1 nor buyer 2 will live in the property" do
expect(sales_log.buy1livein).to be 2
expect(sales_log.buy2livein).to be 2
end
end
end
end end
context "when saving addresses" do context "when saving addresses" do

57
spec/models/validations/sales/household_validations_spec.rb

@ -201,4 +201,61 @@ RSpec.describe Validations::Sales::HouseholdValidations do
end end
end end
end end
describe "validating fields about buyers living in the property" do
let(:sales_log) { FactoryBot.create(:sales_log, :outright_sale_setup_complete, noint: 1, companybuy: 2, buylivein:, jointpur:, jointmore:, buy1livein:) }
context "when buyers will live in the property and the sale is a joint purchase" do
let(:buylivein) { 1 }
let(:jointpur) { 1 }
let(:jointmore) { 2 }
context "and buyer one will live in the property" do
let(:buy1livein) { 1 }
it "does not add validations regardless of whether buyer two will live in the property" do
sales_log.buy2livein = 1
household_validator.validate_buyers_living_in_property(sales_log)
expect(sales_log.errors).to be_empty
sales_log.buy2livein = 2
household_validator.validate_buyers_living_in_property(sales_log)
expect(sales_log.errors).to be_empty
end
end
context "and buyer one will not live in the property" do
let(:buy1livein) { 2 }
it "does not add validations if buyer two will live in the property or if we do not yet know" do
sales_log.buy2livein = 1
household_validator.validate_buyers_living_in_property(sales_log)
expect(sales_log.errors).to be_empty
sales_log.buy2livein = nil
household_validator.validate_buyers_living_in_property(sales_log)
expect(sales_log.errors).to be_empty
end
it "triggers a validation if buyer two will also not live in the property" do
sales_log.buy2livein = 2
household_validator.validate_buyers_living_in_property(sales_log)
expect(sales_log.errors[:buylivein]).to include I18n.t("validations.household.buylivein.buyers_will_live_in_property_values_inconsistent_setup")
expect(sales_log.errors[:buy2livein]).to include I18n.t("validations.household.buylivein.buyers_will_live_in_property_values_inconsistent")
expect(sales_log.errors[:buy1livein]).to include I18n.t("validations.household.buylivein.buyers_will_live_in_property_values_inconsistent")
end
end
context "and we don't know whether buyer one will live in the property" do
let(:buy1livein) { nil }
it "does not add validations regardless of whether buyer two will live in the property" do
sales_log.buy2livein = 1
household_validator.validate_buyers_living_in_property(sales_log)
expect(sales_log.errors).to be_empty
sales_log.buy2livein = 2
household_validator.validate_buyers_living_in_property(sales_log)
expect(sales_log.errors).to be_empty
end
end
end
end
end end

Loading…
Cancel
Save