diff --git a/app/models/form/sales/questions/discount.rb b/app/models/form/sales/questions/discount.rb index dc071c00e..fdee1e11c 100644 --- a/app/models/form/sales/questions/discount.rb +++ b/app/models/form/sales/questions/discount.rb @@ -7,7 +7,7 @@ class Form::Sales::Questions::Discount < ::Form::Question @type = "numeric" @min = 0 @max = form.start_year_after_2024? ? 70 : 100 - @step = 1 + @step = 0.1 @width = 5 @suffix = "%" @hint_text = "For Right to Buy (RTB), Preserved Right to Buy (PRTB), and Voluntary Right to Buy (VRTB)

diff --git a/app/models/validations/sales/sale_information_validations.rb b/app/models/validations/sales/sale_information_validations.rb index 86295ceb3..979757e51 100644 --- a/app/models/validations/sales/sale_information_validations.rb +++ b/app/models/validations/sales/sale_information_validations.rb @@ -47,7 +47,10 @@ module Validations::Sales::SaleInformationValidations return unless record.mortgage || record.mortgageused == 2 || record.mortgageused == 3 return unless record.discount || record.grant || record.type == 29 - if over_tolerance?(record.mortgage_deposit_and_grant_total, record.value_with_discount, 1) && record.discounted_ownership_sale? + # When a percentage discount is used, a percentage tolerance is needed to account for rounding errors + tolerance = record.discount ? record.value * 0.05 / 100 : 1 + + if over_tolerance?(record.mortgage_deposit_and_grant_total, record.value_with_discount, tolerance, strict: !record.discount.nil?) && record.discounted_ownership_sale? %i[mortgageused mortgage value deposit ownershipsch discount grant].each do |field| record.errors.add field, I18n.t("validations.sale_information.discounted_ownership_value", mortgage_deposit_and_grant_total: record.field_formatted_as_currency("mortgage_deposit_and_grant_total"), value_with_discount: record.field_formatted_as_currency("value_with_discount")) end @@ -247,7 +250,11 @@ module Validations::Sales::SaleInformationValidations end end - def over_tolerance?(expected, actual, tolerance) - (expected - actual).abs >= tolerance + def over_tolerance?(expected, actual, tolerance, strict: false) + if strict + (expected - actual).abs > tolerance + else + (expected - actual).abs >= tolerance + end end end diff --git a/app/models/validations/sales/soft_validations.rb b/app/models/validations/sales/soft_validations.rb index 51326a2f4..fccd9bf83 100644 --- a/app/models/validations/sales/soft_validations.rb +++ b/app/models/validations/sales/soft_validations.rb @@ -68,6 +68,7 @@ module Validations::Sales::SoftValidations end def extra_borrowing_expected_but_not_reported? + return unless saledate && !form.start_year_after_2024? return unless extrabor && mortgage && deposit && value && discount extrabor != 1 && mortgage + deposit > value - value * discount / 100 diff --git a/spec/models/validations/sales/sale_information_validations_spec.rb b/spec/models/validations/sales/sale_information_validations_spec.rb index bfc9b579c..20887bf97 100644 --- a/spec/models/validations/sales/sale_information_validations_spec.rb +++ b/spec/models/validations/sales/sale_information_validations_spec.rb @@ -204,190 +204,113 @@ RSpec.describe Validations::Sales::SaleInformationValidations do end describe "#validate_discounted_ownership_value" do - let(:record) { FactoryBot.build(:sales_log, mortgage: 10_000, deposit: 5_000, value: 30_000, ownershipsch: 2, type: 8, saledate: now) } + let(:record) { FactoryBot.build(:sales_log, :saledate_today, mortgage: 10_000, deposit: 5_000, value: 30_000, ownershipsch: 2, type: 8) } - around do |example| - Timecop.freeze(now) do - example.run - end - Timecop.return - end - - context "with a log in the 24/25 collection year" do - let(:now) { Time.zone.local(2024, 4, 1) } - - context "when grant is routed to" do - context "and not provided" do - before do - record.grant = nil - end + context "when grant is routed to" do + let(:record) { FactoryBot.build(:sales_log, :saledate_today, deposit: nil, ownershipsch: 2, type: 8) } - it "returns false" do - sale_information_validator.validate_discounted_ownership_value(record) - expect(record.errors["mortgageused"]).to be_empty - expect(record.errors["mortgage"]).to be_empty - expect(record.errors["value"]).to be_empty - expect(record.errors["deposit"]).to be_empty - expect(record.errors["ownershipsch"]).to be_empty - expect(record.errors["discount"]).to be_empty - expect(record.errors["grant"]).to be_empty - end + context "and not provided" do + before do + record.grant = nil end - context "and is provided" do - it "adds an error if mortgage, deposit and grant at least 1 greater than discounted value" do - record.mortgage = 30_000 - record.deposit = 5_000 - record.grant = 15_000 - record.value = 99_998 - record.discount = 50 - sale_information_validator.validate_discounted_ownership_value(record) - expect(record.errors["mortgageused"]).to include("The mortgage, deposit, and grant when added together is £50,000.00, and the purchase price times by the discount is £49,999.00. These figures should be the same") - expect(record.errors["mortgage"]).to include("The mortgage, deposit, and grant when added together is £50,000.00, and the purchase price times by the discount is £49,999.00. These figures should be the same") - expect(record.errors["value"]).to include("The mortgage, deposit, and grant when added together is £50,000.00, and the purchase price times by the discount is £49,999.00. These figures should be the same") - expect(record.errors["deposit"]).to include("The mortgage, deposit, and grant when added together is £50,000.00, and the purchase price times by the discount is £49,999.00. These figures should be the same") - expect(record.errors["ownershipsch"]).to include("The mortgage, deposit, and grant when added together is £50,000.00, and the purchase price times by the discount is £49,999.00. These figures should be the same") - expect(record.errors["discount"]).to include("The mortgage, deposit, and grant when added together is £50,000.00, and the purchase price times by the discount is £49,999.00. These figures should be the same") - expect(record.errors["grant"]).to include("The mortgage, deposit, and grant when added together is £50,000.00, and the purchase price times by the discount is £49,999.00. These figures should be the same") - end - - it "adds an error if mortgage, deposit and grant at least 1 less than discounted value" do - record.mortgage = 30_000 - record.deposit = 5_000 - record.grant = 15_000 - record.value = 100_002 - record.discount = 50 - sale_information_validator.validate_discounted_ownership_value(record) - expect(record.errors["mortgageused"]).to include("The mortgage, deposit, and grant when added together is £50,000.00, and the purchase price times by the discount is £50,001.00. These figures should be the same") - expect(record.errors["mortgage"]).to include("The mortgage, deposit, and grant when added together is £50,000.00, and the purchase price times by the discount is £50,001.00. These figures should be the same") - expect(record.errors["value"]).to include("The mortgage, deposit, and grant when added together is £50,000.00, and the purchase price times by the discount is £50,001.00. These figures should be the same") - expect(record.errors["deposit"]).to include("The mortgage, deposit, and grant when added together is £50,000.00, and the purchase price times by the discount is £50,001.00. These figures should be the same") - expect(record.errors["ownershipsch"]).to include("The mortgage, deposit, and grant when added together is £50,000.00, and the purchase price times by the discount is £50,001.00. These figures should be the same") - expect(record.errors["discount"]).to include("The mortgage, deposit, and grant when added together is £50,000.00, and the purchase price times by the discount is £50,001.00. These figures should be the same") - expect(record.errors["grant"]).to include("The mortgage, deposit, and grant when added together is £50,000.00, and the purchase price times by the discount is £50,001.00. These figures should be the same") - end + it "returns false" do + sale_information_validator.validate_discounted_ownership_value(record) + expect(record.errors["mortgageused"]).to be_empty + expect(record.errors["mortgage"]).to be_empty + expect(record.errors["value"]).to be_empty + expect(record.errors["deposit"]).to be_empty + expect(record.errors["ownershipsch"]).to be_empty + expect(record.errors["discount"]).to be_empty + expect(record.errors["grant"]).to be_empty + end + end - it "does not add an error if mortgage, deposit and grant less than 1 greater than discounted value" do - record.mortgage = 30_000 - record.deposit = 5_000 - record.grant = 15_000 - record.value = 99_999 - record.discount = 50 + context "and is provided" do + it "adds an error if mortgage, deposit and grant at least 1 greater than discounted value" do + record.mortgage = 30_000 + record.deposit = 5_000 + record.grant = 15_000 + record.value = 49_999 - sale_information_validator.validate_discounted_ownership_value(record) + sale_information_validator.validate_discounted_ownership_value(record) - expect(record.errors["mortgageused"]).to be_empty - expect(record.errors["mortgage"]).to be_empty - expect(record.errors["value"]).to be_empty - expect(record.errors["deposit"]).to be_empty - expect(record.errors["ownershipsch"]).to be_empty - expect(record.errors["discount"]).to be_empty - expect(record.errors["grant"]).to be_empty - end + expect(record.errors["mortgageused"]).to include("The mortgage, deposit, and grant when added together is £50,000.00, and the purchase price times by the discount is £49,999.00. These figures should be the same") + expect(record.errors["mortgage"]).to include("The mortgage, deposit, and grant when added together is £50,000.00, and the purchase price times by the discount is £49,999.00. These figures should be the same") + expect(record.errors["value"]).to include("The mortgage, deposit, and grant when added together is £50,000.00, and the purchase price times by the discount is £49,999.00. These figures should be the same") + expect(record.errors["deposit"]).to include("The mortgage, deposit, and grant when added together is £50,000.00, and the purchase price times by the discount is £49,999.00. These figures should be the same") + expect(record.errors["ownershipsch"]).to include("The mortgage, deposit, and grant when added together is £50,000.00, and the purchase price times by the discount is £49,999.00. These figures should be the same") + expect(record.errors["discount"]).to include("The mortgage, deposit, and grant when added together is £50,000.00, and the purchase price times by the discount is £49,999.00. These figures should be the same") + expect(record.errors["grant"]).to include("The mortgage, deposit, and grant when added together is £50,000.00, and the purchase price times by the discount is £49,999.00. These figures should be the same") + end - it "does not add an error if mortgage, deposit and grant less than 1 less than discounted value" do - record.mortgage = 30_000 - record.deposit = 5_000 - record.grant = 15_000 - record.value = 100_001 - record.discount = 50 + it "adds an error if mortgage, deposit and grant at least 1 less than discounted value" do + record.mortgage = 30_000 + record.deposit = 5_000 + record.grant = 15_000 + record.value = 50_001 - sale_information_validator.validate_discounted_ownership_value(record) + sale_information_validator.validate_discounted_ownership_value(record) - expect(record.errors["mortgageused"]).to be_empty - expect(record.errors["mortgage"]).to be_empty - expect(record.errors["value"]).to be_empty - expect(record.errors["deposit"]).to be_empty - expect(record.errors["ownershipsch"]).to be_empty - expect(record.errors["discount"]).to be_empty - expect(record.errors["grant"]).to be_empty - end + expect(record.errors["mortgageused"]).to include("The mortgage, deposit, and grant when added together is £50,000.00, and the purchase price times by the discount is £50,001.00. These figures should be the same") + expect(record.errors["mortgage"]).to include("The mortgage, deposit, and grant when added together is £50,000.00, and the purchase price times by the discount is £50,001.00. These figures should be the same") + expect(record.errors["value"]).to include("The mortgage, deposit, and grant when added together is £50,000.00, and the purchase price times by the discount is £50,001.00. These figures should be the same") + expect(record.errors["deposit"]).to include("The mortgage, deposit, and grant when added together is £50,000.00, and the purchase price times by the discount is £50,001.00. These figures should be the same") + expect(record.errors["ownershipsch"]).to include("The mortgage, deposit, and grant when added together is £50,000.00, and the purchase price times by the discount is £50,001.00. These figures should be the same") + expect(record.errors["discount"]).to include("The mortgage, deposit, and grant when added together is £50,000.00, and the purchase price times by the discount is £50,001.00. These figures should be the same") + expect(record.errors["grant"]).to include("The mortgage, deposit, and grant when added together is £50,000.00, and the purchase price times by the discount is £50,001.00. These figures should be the same") + end - it "does not add an error if mortgage, deposit and grant total equals discounted value" do - record.mortgage = 30_000 - record.deposit = 5_000 - record.grant = 15_000 - record.value = 100_000 - record.discount = 50 + it "does not add an error if mortgage, deposit and grant total equals discounted value" do + record.mortgage = 30_000 + record.deposit = 5_000 + record.grant = 15_000 + record.value = 50_000 - sale_information_validator.validate_discounted_ownership_value(record) + sale_information_validator.validate_discounted_ownership_value(record) - expect(record.errors["mortgageused"]).to be_empty - expect(record.errors["mortgage"]).to be_empty - expect(record.errors["value"]).to be_empty - expect(record.errors["deposit"]).to be_empty - expect(record.errors["ownershipsch"]).to be_empty - expect(record.errors["discount"]).to be_empty - expect(record.errors["grant"]).to be_empty - end + expect(record.errors["mortgageused"]).to be_empty + expect(record.errors["mortgage"]).to be_empty + expect(record.errors["value"]).to be_empty + expect(record.errors["deposit"]).to be_empty + expect(record.errors["ownershipsch"]).to be_empty + expect(record.errors["discount"]).to be_empty + expect(record.errors["grant"]).to be_empty end end + end - context "when discount is routed to" do - let(:record) { FactoryBot.build(:sales_log, mortgage: 10_000, deposit: 5_000, value: 30_000, ownershipsch: 2, type: 9, saledate: now) } - - context "and not provided" do - before do - record.discount = nil - end + context "when discount is routed to" do + let(:record) { FactoryBot.build(:sales_log, :saledate_today, grant: nil, ownershipsch: 2, type: 9) } - it "returns false" do - sale_information_validator.validate_discounted_ownership_value(record) - expect(record.errors["mortgageused"]).to be_empty - expect(record.errors["mortgage"]).to be_empty - expect(record.errors["value"]).to be_empty - expect(record.errors["deposit"]).to be_empty - expect(record.errors["ownershipsch"]).to be_empty - expect(record.errors["discount"]).to be_empty - expect(record.errors["grant"]).to be_empty - end - end + context "and not provided" do + it "returns false" do + record.value = 30_000 + record.mortgage = 10_000 + record.deposit = 5_000 + record.discount = nil - context "and is provided" do - it "returns true if mortgage and deposit total does not equal market value - discount" do - record.discount = 10 - sale_information_validator.validate_discounted_ownership_value(record) - expect(record.errors["mortgageused"]).to include("The mortgage, deposit, and grant when added together is £15,000.00, and the purchase price times by the discount is £27,000.00. These figures should be the same") - expect(record.errors["mortgage"]).to include("The mortgage, deposit, and grant when added together is £15,000.00, and the purchase price times by the discount is £27,000.00. These figures should be the same") - expect(record.errors["value"]).to include("The mortgage, deposit, and grant when added together is £15,000.00, and the purchase price times by the discount is £27,000.00. These figures should be the same") - expect(record.errors["deposit"]).to include("The mortgage, deposit, and grant when added together is £15,000.00, and the purchase price times by the discount is £27,000.00. These figures should be the same") - expect(record.errors["ownershipsch"]).to include("The mortgage, deposit, and grant when added together is £15,000.00, and the purchase price times by the discount is £27,000.00. These figures should be the same") - expect(record.errors["discount"]).to include("The mortgage, deposit, and grant when added together is £15,000.00, and the purchase price times by the discount is £27,000.00. These figures should be the same") - expect(record.errors["grant"]).to include("The mortgage, deposit, and grant when added together is £15,000.00, and the purchase price times by the discount is £27,000.00. These figures should be the same") - end + sale_information_validator.validate_discounted_ownership_value(record) - it "returns false if mortgage and deposit total equals market value - discount" do - record.discount = 50 - sale_information_validator.validate_discounted_ownership_value(record) - expect(record.errors["mortgageused"]).to be_empty - expect(record.errors["mortgage"]).to be_empty - expect(record.errors["value"]).to be_empty - expect(record.errors["deposit"]).to be_empty - expect(record.errors["ownershipsch"]).to be_empty - expect(record.errors["discount"]).to be_empty - expect(record.errors["grant"]).to be_empty - end + expect(record.errors["mortgageused"]).to be_empty + expect(record.errors["mortgage"]).to be_empty + expect(record.errors["value"]).to be_empty + expect(record.errors["deposit"]).to be_empty + expect(record.errors["ownershipsch"]).to be_empty + expect(record.errors["discount"]).to be_empty + expect(record.errors["grant"]).to be_empty end end - context "when neither discount nor grant is routed to" do - let(:record) { FactoryBot.build(:sales_log, mortgage: 10_000, value: 30_000, ownershipsch: 2, type: 29, saledate: now) } + context "and is provided" do + it "does not add errors if mortgage and deposit total equals market value - discount" do + record.value = 30_000 + record.mortgage = 10_000 + record.deposit = 5_000 + record.discount = 50 - it "returns true if mortgage and deposit total does not equal market value" do - record.deposit = 2_000 sale_information_validator.validate_discounted_ownership_value(record) - expect(record.errors["mortgageused"]).to include("The mortgage, deposit, and grant when added together is £12,000.00, and the purchase price times by the discount is £30,000.00. These figures should be the same") - expect(record.errors["mortgage"]).to include("The mortgage, deposit, and grant when added together is £12,000.00, and the purchase price times by the discount is £30,000.00. These figures should be the same") - expect(record.errors["value"]).to include("The mortgage, deposit, and grant when added together is £12,000.00, and the purchase price times by the discount is £30,000.00. These figures should be the same") - expect(record.errors["deposit"]).to include("The mortgage, deposit, and grant when added together is £12,000.00, and the purchase price times by the discount is £30,000.00. These figures should be the same") - expect(record.errors["ownershipsch"]).to include("The mortgage, deposit, and grant when added together is £12,000.00, and the purchase price times by the discount is £30,000.00. These figures should be the same") - expect(record.errors["discount"]).to include("The mortgage, deposit, and grant when added together is £12,000.00, and the purchase price times by the discount is £30,000.00. These figures should be the same") - expect(record.errors["grant"]).to include("The mortgage, deposit, and grant when added together is £12,000.00, and the purchase price times by the discount is £30,000.00. These figures should be the same") - end - it "returns false if mortgage and deposit total equals market value" do - record.deposit = 20_000 - sale_information_validator.validate_discounted_ownership_value(record) expect(record.errors["mortgageused"]).to be_empty expect(record.errors["mortgage"]).to be_empty expect(record.errors["value"]).to be_empty @@ -396,72 +319,49 @@ RSpec.describe Validations::Sales::SaleInformationValidations do expect(record.errors["discount"]).to be_empty expect(record.errors["grant"]).to be_empty end - end - context "when mortgage is routed to" do - let(:record) { FactoryBot.build(:sales_log, mortgageused: 1, deposit: 5_000, grant: 3_000, value: 20_000, discount: 10, ownershipsch: 2, saledate: now) } + it "does not add errors if mortgage and deposit total is within a 0.05% x market value tolerance of market value - discount" do + record.value = 123_000 + record.mortgage = 66_112 + record.deposit = 0 + record.discount = 46.3 - context "and not provided" do - before do - record.mortgage = nil - end + sale_information_validator.validate_discounted_ownership_value(record) - it "returns false" do - sale_information_validator.validate_discounted_ownership_value(record) - expect(record.errors["mortgageused"]).to be_empty - expect(record.errors["mortgage"]).to be_empty - expect(record.errors["value"]).to be_empty - expect(record.errors["deposit"]).to be_empty - expect(record.errors["ownershipsch"]).to be_empty - expect(record.errors["discount"]).to be_empty - expect(record.errors["grant"]).to be_empty - end + expect(record.errors["mortgageused"]).to be_empty + expect(record.errors["mortgage"]).to be_empty + expect(record.errors["value"]).to be_empty + expect(record.errors["deposit"]).to be_empty + expect(record.errors["ownershipsch"]).to be_empty + expect(record.errors["discount"]).to be_empty + expect(record.errors["grant"]).to be_empty end - context "and is provided" do - it "returns true if mortgage, grant and deposit total does not equal market value - discount" do - record.mortgage = 10 - sale_information_validator.validate_discounted_ownership_value(record) - expect(record.errors["mortgageused"]).to include("The mortgage, deposit, and grant when added together is £8,010.00, and the purchase price times by the discount is £18,000.00. These figures should be the same") - expect(record.errors["mortgage"]).to include("The mortgage, deposit, and grant when added together is £8,010.00, and the purchase price times by the discount is £18,000.00. These figures should be the same") - expect(record.errors["value"]).to include("The mortgage, deposit, and grant when added together is £8,010.00, and the purchase price times by the discount is £18,000.00. These figures should be the same") - expect(record.errors["deposit"]).to include("The mortgage, deposit, and grant when added together is £8,010.00, and the purchase price times by the discount is £18,000.00. These figures should be the same") - expect(record.errors["ownershipsch"]).to include("The mortgage, deposit, and grant when added together is £8,010.00, and the purchase price times by the discount is £18,000.00. These figures should be the same") - expect(record.errors["discount"]).to include("The mortgage, deposit, and grant when added together is £8,010.00, and the purchase price times by the discount is £18,000.00. These figures should be the same") - expect(record.errors["grant"]).to include("The mortgage, deposit, and grant when added together is £8,010.00, and the purchase price times by the discount is £18,000.00. These figures should be the same") - end + it "adds errors if mortgage and deposit total is not within a 0.05% x market value tolerance of market value - discount" do + record.value = 123_000 + record.mortgage = 66_113 + record.deposit = 0 + record.discount = 46.3 - it "returns false if mortgage, grant and deposit total equals market value - discount" do - record.mortgage = 10_000 - sale_information_validator.validate_discounted_ownership_value(record) - expect(record.errors["mortgageused"]).to be_empty - expect(record.errors["mortgage"]).to be_empty - expect(record.errors["value"]).to be_empty - expect(record.errors["deposit"]).to be_empty - expect(record.errors["ownershipsch"]).to be_empty - expect(record.errors["discount"]).to be_empty - expect(record.errors["grant"]).to be_empty - end + sale_information_validator.validate_discounted_ownership_value(record) + + expect(record.errors["mortgageused"]).to include("The mortgage, deposit, and grant when added together is £66,113.00, and the purchase price times by the discount is £66,051.00. These figures should be the same") + expect(record.errors["mortgage"]).to include("The mortgage, deposit, and grant when added together is £66,113.00, and the purchase price times by the discount is £66,051.00. These figures should be the same") + expect(record.errors["value"]).to include("The mortgage, deposit, and grant when added together is £66,113.00, and the purchase price times by the discount is £66,051.00. These figures should be the same") + expect(record.errors["deposit"]).to include("The mortgage, deposit, and grant when added together is £66,113.00, and the purchase price times by the discount is £66,051.00. These figures should be the same") + expect(record.errors["ownershipsch"]).to include("The mortgage, deposit, and grant when added together is £66,113.00, and the purchase price times by the discount is £66,051.00. These figures should be the same") + expect(record.errors["discount"]).to include("The mortgage, deposit, and grant when added together is £66,113.00, and the purchase price times by the discount is £66,051.00. These figures should be the same") + expect(record.errors["grant"]).to include("The mortgage, deposit, and grant when added together is £66,113.00, and the purchase price times by the discount is £66,051.00. These figures should be the same") end - end - context "when mortgage is not routed to" do - let(:record) { FactoryBot.build(:sales_log, mortgageused: 2, deposit: 5_000, grant: 3_000, value: 20_000, discount: 10, ownershipsch: 2, saledate: now) } + it "does not add errors if mortgage and deposit total is exactly 0.05% x market value away from market value - discount" do + record.value = 120_000 + record.mortgage = 64_500 + record.deposit = 0 + record.discount = 46.3 - it "returns true if grant and deposit total does not equal market value - discount" do sale_information_validator.validate_discounted_ownership_value(record) - expect(record.errors["mortgageused"]).to include("The mortgage, deposit, and grant when added together is £8,000.00, and the purchase price times by the discount is £18,000.00. These figures should be the same") - expect(record.errors["mortgage"]).to include("The mortgage, deposit, and grant when added together is £8,000.00, and the purchase price times by the discount is £18,000.00. These figures should be the same") - expect(record.errors["value"]).to include("The mortgage, deposit, and grant when added together is £8,000.00, and the purchase price times by the discount is £18,000.00. These figures should be the same") - expect(record.errors["deposit"]).to include("The mortgage, deposit, and grant when added together is £8,000.00, and the purchase price times by the discount is £18,000.00. These figures should be the same") - expect(record.errors["ownershipsch"]).to include("The mortgage, deposit, and grant when added together is £8,000.00, and the purchase price times by the discount is £18,000.00. These figures should be the same") - expect(record.errors["discount"]).to include("The mortgage, deposit, and grant when added together is £8,000.00, and the purchase price times by the discount is £18,000.00. These figures should be the same") - expect(record.errors["grant"]).to include("The mortgage, deposit, and grant when added together is £8,000.00, and the purchase price times by the discount is £18,000.00. These figures should be the same") - end - it "returns false if mortgage, grant and deposit total equals market value - discount" do - record.grant = 13_000 - sale_information_validator.validate_discounted_ownership_value(record) expect(record.errors["mortgageused"]).to be_empty expect(record.errors["mortgage"]).to be_empty expect(record.errors["value"]).to be_empty @@ -471,9 +371,43 @@ RSpec.describe Validations::Sales::SaleInformationValidations do expect(record.errors["grant"]).to be_empty end end + end + + context "when neither discount nor grant is routed to" do + let(:record) { FactoryBot.build(:sales_log, :saledate_today, mortgage: 10_000, value: 30_000, ownershipsch: 2, type: 29) } + + it "returns true if mortgage and deposit total does not equal market value" do + record.deposit = 2_000 + sale_information_validator.validate_discounted_ownership_value(record) + expect(record.errors["mortgageused"]).to include("The mortgage, deposit, and grant when added together is £12,000.00, and the purchase price times by the discount is £30,000.00. These figures should be the same") + expect(record.errors["mortgage"]).to include("The mortgage, deposit, and grant when added together is £12,000.00, and the purchase price times by the discount is £30,000.00. These figures should be the same") + expect(record.errors["value"]).to include("The mortgage, deposit, and grant when added together is £12,000.00, and the purchase price times by the discount is £30,000.00. These figures should be the same") + expect(record.errors["deposit"]).to include("The mortgage, deposit, and grant when added together is £12,000.00, and the purchase price times by the discount is £30,000.00. These figures should be the same") + expect(record.errors["ownershipsch"]).to include("The mortgage, deposit, and grant when added together is £12,000.00, and the purchase price times by the discount is £30,000.00. These figures should be the same") + expect(record.errors["discount"]).to include("The mortgage, deposit, and grant when added together is £12,000.00, and the purchase price times by the discount is £30,000.00. These figures should be the same") + expect(record.errors["grant"]).to include("The mortgage, deposit, and grant when added together is £12,000.00, and the purchase price times by the discount is £30,000.00. These figures should be the same") + end + + it "returns false if mortgage and deposit total equals market value" do + record.deposit = 20_000 + sale_information_validator.validate_discounted_ownership_value(record) + expect(record.errors["mortgageused"]).to be_empty + expect(record.errors["mortgage"]).to be_empty + expect(record.errors["value"]).to be_empty + expect(record.errors["deposit"]).to be_empty + expect(record.errors["ownershipsch"]).to be_empty + expect(record.errors["discount"]).to be_empty + expect(record.errors["grant"]).to be_empty + end + end + + context "when mortgage is routed to" do + let(:record) { FactoryBot.build(:sales_log, :saledate_today, mortgageused: 1, deposit: 5_000, grant: 3_000, value: 20_000, discount: 10, ownershipsch: 2) } - context "when ownership is not discounted" do - let(:record) { FactoryBot.build(:sales_log, mortgage: 10_000, deposit: 5_000, grant: 3_000, value: 20_000, discount: 10, ownershipsch: 1, saledate: now) } + context "and not provided" do + before do + record.mortgage = nil + end it "returns false" do sale_information_validator.validate_discounted_ownership_value(record) @@ -487,12 +421,22 @@ RSpec.describe Validations::Sales::SaleInformationValidations do end end - context "when it is a 2023 log" do - let(:record) { FactoryBot.build(:sales_log, mortgageused: 1, deposit: 5_000, grant: 3_000, value: 20_000, discount: 10, ownershipsch: 2, saledate: Time.zone.local(2023, 4, 1)) } - - it "returns false" do + context "and is provided" do + it "returns true if mortgage, grant and deposit total does not equal market value - discount" do record.mortgage = 10 sale_information_validator.validate_discounted_ownership_value(record) + expect(record.errors["mortgageused"]).to include("The mortgage, deposit, and grant when added together is £8,010.00, and the purchase price times by the discount is £18,000.00. These figures should be the same") + expect(record.errors["mortgage"]).to include("The mortgage, deposit, and grant when added together is £8,010.00, and the purchase price times by the discount is £18,000.00. These figures should be the same") + expect(record.errors["value"]).to include("The mortgage, deposit, and grant when added together is £8,010.00, and the purchase price times by the discount is £18,000.00. These figures should be the same") + expect(record.errors["deposit"]).to include("The mortgage, deposit, and grant when added together is £8,010.00, and the purchase price times by the discount is £18,000.00. These figures should be the same") + expect(record.errors["ownershipsch"]).to include("The mortgage, deposit, and grant when added together is £8,010.00, and the purchase price times by the discount is £18,000.00. These figures should be the same") + expect(record.errors["discount"]).to include("The mortgage, deposit, and grant when added together is £8,010.00, and the purchase price times by the discount is £18,000.00. These figures should be the same") + expect(record.errors["grant"]).to include("The mortgage, deposit, and grant when added together is £8,010.00, and the purchase price times by the discount is £18,000.00. These figures should be the same") + end + + it "returns false if mortgage, grant and deposit total equals market value - discount" do + record.mortgage = 10_000 + sale_information_validator.validate_discounted_ownership_value(record) expect(record.errors["mortgageused"]).to be_empty expect(record.errors["mortgage"]).to be_empty expect(record.errors["value"]).to be_empty @@ -503,6 +447,64 @@ RSpec.describe Validations::Sales::SaleInformationValidations do end end end + + context "when mortgage is not routed to" do + let(:record) { FactoryBot.build(:sales_log, :saledate_today, mortgageused: 2, deposit: 5_000, grant: 3_000, value: 20_000, discount: 10, ownershipsch: 2) } + + it "returns true if grant and deposit total does not equal market value - discount" do + sale_information_validator.validate_discounted_ownership_value(record) + expect(record.errors["mortgageused"]).to include("The mortgage, deposit, and grant when added together is £8,000.00, and the purchase price times by the discount is £18,000.00. These figures should be the same") + expect(record.errors["mortgage"]).to include("The mortgage, deposit, and grant when added together is £8,000.00, and the purchase price times by the discount is £18,000.00. These figures should be the same") + expect(record.errors["value"]).to include("The mortgage, deposit, and grant when added together is £8,000.00, and the purchase price times by the discount is £18,000.00. These figures should be the same") + expect(record.errors["deposit"]).to include("The mortgage, deposit, and grant when added together is £8,000.00, and the purchase price times by the discount is £18,000.00. These figures should be the same") + expect(record.errors["ownershipsch"]).to include("The mortgage, deposit, and grant when added together is £8,000.00, and the purchase price times by the discount is £18,000.00. These figures should be the same") + expect(record.errors["discount"]).to include("The mortgage, deposit, and grant when added together is £8,000.00, and the purchase price times by the discount is £18,000.00. These figures should be the same") + expect(record.errors["grant"]).to include("The mortgage, deposit, and grant when added together is £8,000.00, and the purchase price times by the discount is £18,000.00. These figures should be the same") + end + + it "returns false if mortgage, grant and deposit total equals market value - discount" do + record.grant = 13_000 + sale_information_validator.validate_discounted_ownership_value(record) + expect(record.errors["mortgageused"]).to be_empty + expect(record.errors["mortgage"]).to be_empty + expect(record.errors["value"]).to be_empty + expect(record.errors["deposit"]).to be_empty + expect(record.errors["ownershipsch"]).to be_empty + expect(record.errors["discount"]).to be_empty + expect(record.errors["grant"]).to be_empty + end + end + + context "when ownership is not discounted" do + let(:record) { FactoryBot.build(:sales_log, :saledate_today, mortgage: 10_000, deposit: 5_000, grant: 3_000, value: 20_000, discount: 10, ownershipsch: 1) } + + it "returns false" do + sale_information_validator.validate_discounted_ownership_value(record) + expect(record.errors["mortgageused"]).to be_empty + expect(record.errors["mortgage"]).to be_empty + expect(record.errors["value"]).to be_empty + expect(record.errors["deposit"]).to be_empty + expect(record.errors["ownershipsch"]).to be_empty + expect(record.errors["discount"]).to be_empty + expect(record.errors["grant"]).to be_empty + end + end + + context "when it is a 2023 log" do + let(:record) { FactoryBot.build(:sales_log, mortgageused: 1, deposit: 5_000, grant: 3_000, value: 20_000, discount: 10, ownershipsch: 2, saledate: Time.zone.local(2023, 4, 1)) } + + it "returns false" do + record.mortgage = 10 + sale_information_validator.validate_discounted_ownership_value(record) + expect(record.errors["mortgageused"]).to be_empty + expect(record.errors["mortgage"]).to be_empty + expect(record.errors["value"]).to be_empty + expect(record.errors["deposit"]).to be_empty + expect(record.errors["ownershipsch"]).to be_empty + expect(record.errors["discount"]).to be_empty + expect(record.errors["grant"]).to be_empty + end + end end describe "#validate_outright_sale_value_matches_mortgage_plus_deposit" do diff --git a/spec/models/validations/sales/soft_validations_spec.rb b/spec/models/validations/sales/soft_validations_spec.rb index b64eb1bde..8ce602d36 100644 --- a/spec/models/validations/sales/soft_validations_spec.rb +++ b/spec/models/validations/sales/soft_validations_spec.rb @@ -267,69 +267,87 @@ RSpec.describe Validations::Sales::SoftValidations do end context "when validating extra borrowing" do - it "returns false if extrabor not present" do - record.mortgage = 50_000 - record.deposit = 40_000 - record.value = 100_000 - record.discount = 11 - expect(record) - .not_to be_extra_borrowing_expected_but_not_reported - end + context "when the log is for 2023" do + let(:record) { build(:sales_log, saledate: Time.zone.local(2023, 12, 1)) } + + it "returns false if extrabor not present" do + record.mortgage = 50_000 + record.deposit = 40_000 + record.value = 100_000 + record.discount = 11 + expect(record) + .not_to be_extra_borrowing_expected_but_not_reported + end - it "returns false if mortgage not present" do - record.extrabor = 2 - record.deposit = 40_000 - record.value = 100_000 - record.discount = 11 - expect(record) - .not_to be_extra_borrowing_expected_but_not_reported - end + it "returns false if mortgage not present" do + record.extrabor = 2 + record.deposit = 40_000 + record.value = 100_000 + record.discount = 11 + expect(record) + .not_to be_extra_borrowing_expected_but_not_reported + end - it "returns false if deposit not present" do - record.extrabor = 2 - record.mortgage = 50_000 - record.value = 100_000 - record.discount = 11 - expect(record) - .not_to be_extra_borrowing_expected_but_not_reported - end + it "returns false if deposit not present" do + record.extrabor = 2 + record.mortgage = 50_000 + record.value = 100_000 + record.discount = 11 + expect(record) + .not_to be_extra_borrowing_expected_but_not_reported + end - it "returns false if value not present" do - record.extrabor = 2 - record.mortgage = 50_000 - record.deposit = 40_000 - record.discount = 11 - expect(record) - .not_to be_extra_borrowing_expected_but_not_reported - end + it "returns false if value not present" do + record.extrabor = 2 + record.mortgage = 50_000 + record.deposit = 40_000 + record.discount = 11 + expect(record) + .not_to be_extra_borrowing_expected_but_not_reported + end - it "returns false if discount not present" do - record.extrabor = 2 - record.mortgage = 50_000 - record.deposit = 40_000 - record.value = 100_000 - expect(record) - .not_to be_extra_borrowing_expected_but_not_reported - end + it "returns false if discount not present" do + record.extrabor = 2 + record.mortgage = 50_000 + record.deposit = 40_000 + record.value = 100_000 + expect(record) + .not_to be_extra_borrowing_expected_but_not_reported + end - it "returns false if extra borrowing expected and reported" do - record.extrabor = 1 - record.mortgage = 50_000 - record.deposit = 40_000 - record.value = 100_000 - record.discount = 11 - expect(record) - .not_to be_extra_borrowing_expected_but_not_reported + it "returns false if extra borrowing expected and reported" do + record.extrabor = 1 + record.mortgage = 50_000 + record.deposit = 40_000 + record.value = 100_000 + record.discount = 11 + expect(record) + .not_to be_extra_borrowing_expected_but_not_reported + end + + it "returns true if extra borrowing expected but not reported" do + record.extrabor = 2 + record.mortgage = 50_000 + record.deposit = 40_000 + record.value = 100_000 + record.discount = 11 + expect(record) + .to be_extra_borrowing_expected_but_not_reported + end end - it "returns true if extra borrowing expected but not reported" do - record.extrabor = 2 - record.mortgage = 50_000 - record.deposit = 40_000 - record.value = 100_000 - record.discount = 11 - expect(record) - .to be_extra_borrowing_expected_but_not_reported + context "when the log is for 2024" do + let(:record) { build(:sales_log, saledate: Time.zone.local(2024, 12, 1)) } + + it "returns false for logs from 2024 onwards" do + record.extrabor = 2 + record.mortgage = 50_000 + record.deposit = 40_000 + record.value = 100_000 + record.discount = 11 + expect(record) + .not_to be_extra_borrowing_expected_but_not_reported + end end end end