Browse Source

CLDC-3447: Allow decimal discount percentage and increased validation tolerance

pull/2427/head
Rachael Booth 2 years ago
parent
commit
d1a0838e70
  1. 2
      app/models/form/sales/questions/discount.rb
  2. 5
      app/models/validations/sales/sale_information_validations.rb
  3. 113
      spec/models/validations/sales/sale_information_validations_spec.rb

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

@ -7,7 +7,7 @@ class Form::Sales::Questions::Discount < ::Form::Question
@type = "numeric" @type = "numeric"
@min = 0 @min = 0
@max = form.start_year_after_2024? ? 70 : 100 @max = form.start_year_after_2024? ? 70 : 100
@step = 1 @step = 0.1
@width = 5 @width = 5
@suffix = "%" @suffix = "%"
@hint_text = "For Right to Buy (RTB), Preserved Right to Buy (PRTB), and Voluntary Right to Buy (VRTB)</br></br> @hint_text = "For Right to Buy (RTB), Preserved Right to Buy (PRTB), and Voluntary Right to Buy (VRTB)</br></br>

5
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.mortgage || record.mortgageused == 2 || record.mortgageused == 3
return unless record.discount || record.grant || record.type == 29 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) && record.discounted_ownership_sale?
%i[mortgageused mortgage value deposit ownershipsch discount grant].each do |field| %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")) 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 end

113
spec/models/validations/sales/sale_information_validations_spec.rb

@ -204,19 +204,11 @@ RSpec.describe Validations::Sales::SaleInformationValidations do
end end
describe "#validate_discounted_ownership_value" do 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 "when grant is routed to" do
let(:record) { FactoryBot.build(:sales_log, :saledate_today, deposit: nil, ownershipsch: 2, type: 8) }
context "and not provided" do context "and not provided" do
before do before do
record.grant = nil record.grant = nil
@ -239,9 +231,10 @@ RSpec.describe Validations::Sales::SaleInformationValidations do
record.mortgage = 30_000 record.mortgage = 30_000
record.deposit = 5_000 record.deposit = 5_000
record.grant = 15_000 record.grant = 15_000
record.value = 99_998 record.value = 49_999
record.discount = 50
sale_information_validator.validate_discounted_ownership_value(record) 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["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["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["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")
@ -255,9 +248,10 @@ RSpec.describe Validations::Sales::SaleInformationValidations do
record.mortgage = 30_000 record.mortgage = 30_000
record.deposit = 5_000 record.deposit = 5_000
record.grant = 15_000 record.grant = 15_000
record.value = 100_002 record.value = 50_001
record.discount = 50
sale_information_validator.validate_discounted_ownership_value(record) 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["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["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["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")
@ -267,12 +261,11 @@ RSpec.describe Validations::Sales::SaleInformationValidations do
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") 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 end
it "does not add an error if mortgage, deposit and grant less than 1 greater than discounted value" do it "does not add an error if mortgage, deposit and grant total equals discounted value" do
record.mortgage = 30_000 record.mortgage = 30_000
record.deposit = 5_000 record.deposit = 5_000
record.grant = 15_000 record.grant = 15_000
record.value = 99_999 record.value = 50_000
record.discount = 50
sale_information_validator.validate_discounted_ownership_value(record) sale_information_validator.validate_discounted_ownership_value(record)
@ -284,13 +277,18 @@ RSpec.describe Validations::Sales::SaleInformationValidations do
expect(record.errors["discount"]).to be_empty expect(record.errors["discount"]).to be_empty
expect(record.errors["grant"]).to be_empty expect(record.errors["grant"]).to be_empty
end end
end
end
it "does not add an error if mortgage, deposit and grant less than 1 less than discounted value" do context "when discount is routed to" do
record.mortgage = 30_000 let(:record) { FactoryBot.build(:sales_log, :saledate_today, grant: nil, ownershipsch: 2, type: 9) }
context "and not provided" do
it "returns false" do
record.value = 30_000
record.mortgage = 10_000
record.deposit = 5_000 record.deposit = 5_000
record.grant = 15_000 record.discount = nil
record.value = 100_001
record.discount = 50
sale_information_validator.validate_discounted_ownership_value(record) sale_information_validator.validate_discounted_ownership_value(record)
@ -302,12 +300,13 @@ RSpec.describe Validations::Sales::SaleInformationValidations do
expect(record.errors["discount"]).to be_empty expect(record.errors["discount"]).to be_empty
expect(record.errors["grant"]).to be_empty expect(record.errors["grant"]).to be_empty
end end
end
it "does not add an error if mortgage, deposit and grant total equals discounted value" do context "and is provided" do
record.mortgage = 30_000 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.deposit = 5_000
record.grant = 15_000
record.value = 100_000
record.discount = 50 record.discount = 50
sale_information_validator.validate_discounted_ownership_value(record) sale_information_validator.validate_discounted_ownership_value(record)
@ -320,19 +319,15 @@ RSpec.describe Validations::Sales::SaleInformationValidations do
expect(record.errors["discount"]).to be_empty expect(record.errors["discount"]).to be_empty
expect(record.errors["grant"]).to be_empty expect(record.errors["grant"]).to be_empty
end end
end
end
context "when discount is routed to" do it "does not add errors if mortgage and deposit total is within a 0.05% x market value tolerance of market value - discount" do
let(:record) { FactoryBot.build(:sales_log, mortgage: 10_000, deposit: 5_000, value: 30_000, ownershipsch: 2, type: 9, saledate: now) } record.value = 100_050
record.mortgage = 54_000
record.deposit = 0
record.discount = 46
context "and not provided" do
before do
record.discount = nil
end
it "returns false" do
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["mortgageused"]).to be_empty
expect(record.errors["mortgage"]).to be_empty expect(record.errors["mortgage"]).to be_empty
expect(record.errors["value"]).to be_empty expect(record.errors["value"]).to be_empty
@ -341,37 +336,28 @@ RSpec.describe Validations::Sales::SaleInformationValidations do
expect(record.errors["discount"]).to be_empty expect(record.errors["discount"]).to be_empty
expect(record.errors["grant"]).to be_empty expect(record.errors["grant"]).to be_empty
end end
end
context "and is provided" do it "adds errors if mortgage and deposit total is not within a 0.05% x market value tolerance of market value - discount" do
it "returns true if mortgage and deposit total does not equal market value - discount" do record.value = 100_050
record.discount = 10 record.mortgage = 54_100
sale_information_validator.validate_discounted_ownership_value(record) record.deposit = 0
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") record.discount = 46
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
it "returns false if mortgage and deposit total equals market value - discount" do
record.discount = 50
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["mortgageused"]).to include("The mortgage, deposit, and grant when added together is £54,100.00, and the purchase price times by the discount is £54,027.00. These figures should be the same")
expect(record.errors["value"]).to be_empty expect(record.errors["mortgage"]).to include("The mortgage, deposit, and grant when added together is £54,100.00, and the purchase price times by the discount is £54,027.00. These figures should be the same")
expect(record.errors["deposit"]).to be_empty expect(record.errors["value"]).to include("The mortgage, deposit, and grant when added together is £54,100.00, and the purchase price times by the discount is £54,027.00. These figures should be the same")
expect(record.errors["ownershipsch"]).to be_empty expect(record.errors["deposit"]).to include("The mortgage, deposit, and grant when added together is £54,100.00, and the purchase price times by the discount is £54,027.00. These figures should be the same")
expect(record.errors["discount"]).to be_empty expect(record.errors["ownershipsch"]).to include("The mortgage, deposit, and grant when added together is £54,100.00, and the purchase price times by the discount is £54,027.00. These figures should be the same")
expect(record.errors["grant"]).to be_empty expect(record.errors["discount"]).to include("The mortgage, deposit, and grant when added together is £54,100.00, and the purchase price times by the discount is £54,027.00. These figures should be the same")
expect(record.errors["grant"]).to include("The mortgage, deposit, and grant when added together is £54,100.00, and the purchase price times by the discount is £54,027.00. These figures should be the same")
end end
end end
end end
context "when neither discount nor grant is routed to" do 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) } 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 it "returns true if mortgage and deposit total does not equal market value" do
record.deposit = 2_000 record.deposit = 2_000
@ -399,7 +385,7 @@ RSpec.describe Validations::Sales::SaleInformationValidations do
end end
context "when mortgage is routed to" do 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) } let(:record) { FactoryBot.build(:sales_log, :saledate_today, mortgageused: 1, deposit: 5_000, grant: 3_000, value: 20_000, discount: 10, ownershipsch: 2) }
context "and not provided" do context "and not provided" do
before do before do
@ -446,7 +432,7 @@ RSpec.describe Validations::Sales::SaleInformationValidations do
end end
context "when mortgage is not routed to" do 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) } 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 it "returns true if grant and deposit total does not equal market value - discount" do
sale_information_validator.validate_discounted_ownership_value(record) sale_information_validator.validate_discounted_ownership_value(record)
@ -473,7 +459,7 @@ RSpec.describe Validations::Sales::SaleInformationValidations do
end end
context "when ownership is not discounted" do 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) } 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 it "returns false" do
sale_information_validator.validate_discounted_ownership_value(record) sale_information_validator.validate_discounted_ownership_value(record)
@ -503,7 +489,6 @@ RSpec.describe Validations::Sales::SaleInformationValidations do
end end
end end
end end
end
describe "#validate_outright_sale_value_matches_mortgage_plus_deposit" do describe "#validate_outright_sale_value_matches_mortgage_plus_deposit" do
context "with a 2024 outright sale log" do context "with a 2024 outright sale log" do

Loading…
Cancel
Save