diff --git a/app/models/derived_variables/sales_log_variables.rb b/app/models/derived_variables/sales_log_variables.rb index b4ff1a671..9151a72f5 100644 --- a/app/models/derived_variables/sales_log_variables.rb +++ b/app/models/derived_variables/sales_log_variables.rb @@ -1,5 +1,7 @@ module DerivedVariables::SalesLogVariables def set_derived_fields! + reset_invalidated_derived_values! + self.ethnic = 17 if ethnic_refused? self.mscharge = nil if no_monthly_leasehold_charges? if exdate.present? @@ -13,9 +15,6 @@ module DerivedVariables::SalesLogVariables self.hoyear = hodate.year end 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.totchild = total_child self.totadult = total_adult + total_elder @@ -30,10 +29,74 @@ module DerivedVariables::SalesLogVariables self.uprn = nil self.uprn_known = 0 end + + set_encoded_derived_values! end 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 return unless hholdcount.present? && jointpur.present? diff --git a/app/models/form/sales/pages/buyer1_live_in_property.rb b/app/models/form/sales/pages/buyer1_live_in_property.rb index 17877ee7b..8ee63d26c 100644 --- a/app/models/form/sales/pages/buyer1_live_in_property.rb +++ b/app/models/form/sales/pages/buyer1_live_in_property.rb @@ -5,9 +5,21 @@ class Form::Sales::Pages::Buyer1LiveInProperty < ::Form::Page @depends_on = [ { "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 diff --git a/app/models/form/sales/pages/buyer2_live_in_property.rb b/app/models/form/sales/pages/buyer2_live_in_property.rb index 193f434f8..a16638c0d 100644 --- a/app/models/form/sales/pages/buyer2_live_in_property.rb +++ b/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" @depends_on = [ { - "joint_purchase?" => 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, + "buyers_will_live_in?" => true, + }, + { "buyer_not_interviewed?" => true, + "joint_purchase?" => true, + "buyers_will_live_in?" => true, }, ] end diff --git a/app/models/form/sales/pages/buyer_company.rb b/app/models/form/sales/pages/buyer_company.rb index b9f628f31..dbe1afcec 100644 --- a/app/models/form/sales/pages/buyer_company.rb +++ b/app/models/form/sales/pages/buyer_company.rb @@ -3,7 +3,7 @@ class Form::Sales::Pages::BuyerCompany < ::Form::Page super @id = "buyer_company" @depends_on = [{ - "ownershipsch" => 3, + "outright_sale?" => true, }] end diff --git a/app/models/sales_log.rb b/app/models/sales_log.rb index 06d1d0f5c..411977ba4 100644 --- a/app/models/sales_log.rb +++ b/app/models/sales_log.rb @@ -26,7 +26,6 @@ class SalesLog < Log validates_with SalesLogValidator 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_previous_postcode_changes!, if: :ppostcode_full_changed? before_validation :reset_location_fields!, unless: :postcode_known? @@ -161,10 +160,26 @@ class SalesLog < Log inc1mort == 1 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? buy2livein == 1 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? buy2living == 2 end @@ -352,12 +367,9 @@ class SalesLog < Log def ownership_scheme case ownershipsch - when 1 - "shared ownership" - when 2 - "discounted ownership" - when 3 - "outright sale" + when 1 then "shared ownership" + when 2 then "discounted ownership" + when 3 then "outright sale" end end end diff --git a/app/models/validations/sales/household_validations.rb b/app/models/validations/sales/household_validations.rb index 5d4552eb3..a0202ce89 100644 --- a/app/models/validations/sales/household_validations.rb +++ b/app/models/validations/sales/household_validations.rb @@ -20,6 +20,16 @@ module Validations::Sales::HouseholdValidations 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 def validate_person_age_matches_relationship(record, person_num) diff --git a/config/locales/en.yml b/config/locales/en.yml index a798a258f..5a3189f03 100644 --- a/config/locales/en.yml +++ b/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" postcode: 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: length: diff --git a/spec/models/form/sales/pages/buyer1_live_in_property_spec.rb b/spec/models/form/sales/pages/buyer1_live_in_property_spec.rb index 27a00d36a..b42dfeef0 100644 --- a/spec/models/form/sales/pages/buyer1_live_in_property_spec.rb +++ b/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 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 diff --git a/spec/models/form/sales/pages/buyer2_live_in_property_spec.rb b/spec/models/form/sales/pages/buyer2_live_in_property_spec.rb index bb6ca4b13..bbb54613a 100644 --- a/spec/models/form/sales/pages/buyer2_live_in_property_spec.rb +++ b/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 expect(page.depends_on).to eq([ { - "joint_purchase?" => 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, + "buyers_will_live_in?" => true, + }, + { "buyer_not_interviewed?" => true, + "joint_purchase?" => true, + "buyers_will_live_in?" => true, }, ]) end diff --git a/spec/models/form/sales/pages/buyer_company_spec.rb b/spec/models/form/sales/pages/buyer_company_spec.rb index 2551f8700..ca78d9204 100644 --- a/spec/models/form/sales/pages/buyer_company_spec.rb +++ b/spec/models/form/sales/pages/buyer_company_spec.rb @@ -28,8 +28,6 @@ RSpec.describe Form::Sales::Pages::BuyerCompany, type: :model do end it "has correct depends_on" do - expect(page.depends_on).to eq([{ - "ownershipsch" => 3, - }]) + expect(page.depends_on).to eq([{ "outright_sale?" => true }]) end end diff --git a/spec/models/sales_log_spec.rb b/spec/models/sales_log_spec.rb index 310fb48d1..bc0a96150 100644 --- a/spec/models/sales_log_spec.rb +++ b/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] expect(record_from_db["mortgage"]).to eq(0.0) 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 context "when saving addresses" do diff --git a/spec/models/validations/sales/household_validations_spec.rb b/spec/models/validations/sales/household_validations_spec.rb index 953f27c1d..925ac1814 100644 --- a/spec/models/validations/sales/household_validations_spec.rb +++ b/spec/models/validations/sales/household_validations_spec.rb @@ -201,4 +201,61 @@ RSpec.describe Validations::Sales::HouseholdValidations do 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