diff --git a/app/models/sales_log.rb b/app/models/sales_log.rb index 13d16a786..b4eab2093 100644 --- a/app/models/sales_log.rb +++ b/app/models/sales_log.rb @@ -272,6 +272,12 @@ class SalesLog < Log value * equity / 100 end + def stairbought_part_of_value + return unless value && stairbought + + value * stairbought / 100 + end + def mortgage_deposit_and_discount_total mortgage_amount = mortgage || 0 deposit_amount = deposit || 0 diff --git a/app/models/validations/sales/sale_information_validations.rb b/app/models/validations/sales/sale_information_validations.rb index 7be2cc957..17f827367 100644 --- a/app/models/validations/sales/sale_information_validations.rb +++ b/app/models/validations/sales/sale_information_validations.rb @@ -121,6 +121,26 @@ module Validations::Sales::SaleInformationValidations end end + def validate_staircasing_mortgage(record) + return unless record.mortgageused && record.value && record.deposit && record.stairbought + return unless record.is_staircase? + return unless record.saledate && record.form.start_year_after_2024? + + if record.mortgage_used? + return unless record.mortgage + + if record.mortgage_and_deposit_total != record.stairbought_part_of_value + %i[mortgage value deposit stairbought].each do |field| + record.errors.add field, I18n.t("validations.sale_information.staircasing_mortgage.mortgage_used", mortgage_and_deposit_total: record.field_formatted_as_currency("mortgage_and_deposit_total"), stairbought_part_of_value: record.field_formatted_as_currency("stairbought_part_of_value")) + end + end + elsif record.deposit != record.stairbought_part_of_value + %i[mortgageused value deposit stairbought].each do |field| + record.errors.add field, I18n.t("validations.sale_information.staircasing_mortgage.mortgage_not_used", deposit: record.field_formatted_as_currency("deposit"), stairbought_part_of_value: record.field_formatted_as_currency("stairbought_part_of_value")) + end + end + end + def validate_mortgage_used_and_stairbought(record) return unless record.stairowned && record.mortgageused return unless record.saledate && record.form.start_year_after_2024? diff --git a/config/locales/en.yml b/config/locales/en.yml index 2589cccdc..2fba138c4 100644 --- a/config/locales/en.yml +++ b/config/locales/en.yml @@ -625,6 +625,9 @@ en: non_staircasing_mortgage: mortgage_used: "The mortgage and deposit added together is %{mortgage_and_deposit_total} and the purchase price times by the equity is %{expected_shared_ownership_deposit_value}. These figures should be the same." mortgage_not_used: "The deposit is %{deposit} and the purchase price times by the equity is %{expected_shared_ownership_deposit_value}. As no mortgage was used, these figures should be the same." + staircasing_mortgage: + mortgage_used: "The mortgage and deposit added together is %{mortgage_and_deposit_total} and the percentage bought times the purchase price is %{stairbought_part_of_value}. These figures should be the same." + mortgage_not_used: "The deposit is %{deposit} and the percentage bought times the purchase price is %{stairbought_part_of_value}. As no mortgage was used, these figures should be the same." stairowned: mortgageused_dont_know: "The percentage owned has to be 100% if the mortgage used is 'Don’t know'" merge_request: diff --git a/spec/models/validations/sales/sale_information_validations_spec.rb b/spec/models/validations/sales/sale_information_validations_spec.rb index a75016352..316f7b7d0 100644 --- a/spec/models/validations/sales/sale_information_validations_spec.rb +++ b/spec/models/validations/sales/sale_information_validations_spec.rb @@ -805,6 +805,143 @@ RSpec.describe Validations::Sales::SaleInformationValidations do end end + describe "#validate_staircasing_mortgage" do + let(:record) { FactoryBot.build(:sales_log, mortgageused: 1, mortgage: 10_000, deposit: 5_000, value: 30_000, stairbought: 28, ownershipsch: 1, type: 30, saledate: now) } + + around do |example| + Timecop.freeze(now) do + Singleton.__init__(FormHandler) + example.run + end + Timecop.return + Singleton.__init__(FormHandler) + end + + context "with a log in the 24/25 collection year" do + let(:now) { Time.zone.local(2024, 4, 4) } + + context "when MORTGAGE + DEPOSIT does not equal STAIRBOUGHT/100 * VALUE" do + context "and it is a staircase transaction" do + before do + record.staircase = 1 + end + + it "adds an error" do + sale_information_validator.validate_staircasing_mortgage(record) + expect(record.errors["mortgage"]).to include("The mortgage and deposit added together is £15,000.00 and the percentage bought times the purchase price is £8,400.00. These figures should be the same.") + expect(record.errors["value"]).to include("The mortgage and deposit added together is £15,000.00 and the percentage bought times the purchase price is £8,400.00. These figures should be the same.") + expect(record.errors["deposit"]).to include("The mortgage and deposit added together is £15,000.00 and the percentage bought times the purchase price is £8,400.00. These figures should be the same.") + expect(record.errors["stairbought"]).to include("The mortgage and deposit added together is £15,000.00 and the percentage bought times the purchase price is £8,400.00. These figures should be the same.") + end + end + + context "and it is not a staircase transaction" do + before do + record.staircase = 2 + end + + it "does not add an error" do + sale_information_validator.validate_staircasing_mortgage(record) + expect(record.errors["mortgage"]).to be_empty + expect(record.errors["value"]).to be_empty + expect(record.errors["deposit"]).to be_empty + expect(record.errors["stairbought"]).to be_empty + end + end + end + + context "when MORTGAGE + DEPOSIT equals STAIRBOUGHT/100 * VALUE" do + let(:record) { FactoryBot.build(:sales_log, mortgage: 10_000, staircase: 1, deposit: 5_000, value: 30_000, stairbought: 50, ownershipsch: 1, type: 30, saledate: now) } + + it "does not add an error" do + sale_information_validator.validate_staircasing_mortgage(record) + expect(record.errors["mortgage"]).to be_empty + expect(record.errors["value"]).to be_empty + expect(record.errors["deposit"]).to be_empty + expect(record.errors["stairbought"]).to be_empty + end + end + end + + context "when it is a 2023 log" do + let(:now) { Time.zone.local(2023, 4, 1) } + let(:record) { FactoryBot.build(:sales_log, mortgage: 10_000, staircase: 1, deposit: 5_000, value: 30_000, stairbought: 28, ownershipsch: 1, type: 30, saledate: now) } + + it "does not add an error" do + sale_information_validator.validate_staircasing_mortgage(record) + expect(record.errors["mortgage"]).to be_empty + expect(record.errors["value"]).to be_empty + expect(record.errors["deposit"]).to be_empty + expect(record.errors["stairbought"]).to be_empty + end + end + + context "when mortgage is not used" do + context "with a log in the 24/25 collection year" do + let(:now) { Time.zone.local(2024, 4, 4) } + + before do + record.mortgageused = 2 + end + + context "when DEPOSIT does not equal STAIRBOUGHT/100 * VALUE" do + context "and it is a staircase transaction" do + before do + record.staircase = 1 + end + + it "adds an error" do + sale_information_validator.validate_staircasing_mortgage(record) + expect(record.errors["mortgageused"]).to include("The deposit is £5,000.00 and the percentage bought times the purchase price is £8,400.00. As no mortgage was used, these figures should be the same.") + expect(record.errors["value"]).to include("The deposit is £5,000.00 and the percentage bought times the purchase price is £8,400.00. As no mortgage was used, these figures should be the same.") + expect(record.errors["deposit"]).to include("The deposit is £5,000.00 and the percentage bought times the purchase price is £8,400.00. As no mortgage was used, these figures should be the same.") + expect(record.errors["stairbought"]).to include("The deposit is £5,000.00 and the percentage bought times the purchase price is £8,400.00. As no mortgage was used, these figures should be the same.") + end + end + + context "and it is not a staircase transaction" do + before do + record.staircase = 2 + end + + it "does not add an error" do + sale_information_validator.validate_staircasing_mortgage(record) + expect(record.errors["mortgageused"]).to be_empty + expect(record.errors["value"]).to be_empty + expect(record.errors["deposit"]).to be_empty + expect(record.errors["stairbought"]).to be_empty + end + end + end + + context "when DEPOSIT equals STAIRBOUGHT/100 * VALUE" do + let(:record) { FactoryBot.build(:sales_log, mortgageused: 2, staircase: 1, deposit: 15_000, value: 30_000, stairbought: 50, ownershipsch: 1, type: 30, saledate: now) } + + it "does not add an error" do + sale_information_validator.validate_staircasing_mortgage(record) + expect(record.errors["mortgageused"]).to be_empty + expect(record.errors["value"]).to be_empty + expect(record.errors["deposit"]).to be_empty + expect(record.errors["stairbought"]).to be_empty + end + end + end + + context "when it is a 2023 log" do + let(:now) { Time.zone.local(2023, 4, 1) } + let(:record) { FactoryBot.build(:sales_log, mortgageused: 2, staircase: 1, deposit: 5_000, value: 30_000, stairbought: 28, ownershipsch: 1, type: 30, saledate: now) } + + it "does not add an error" do + sale_information_validator.validate_staircasing_mortgage(record) + expect(record.errors["mortgageused"]).to be_empty + expect(record.errors["value"]).to be_empty + expect(record.errors["deposit"]).to be_empty + expect(record.errors["stairbought"]).to be_empty + end + end + end + end + describe "#validate_mortgage_used_and_stairbought" do let(:now) { Time.zone.local(2024, 4, 4) } diff --git a/spec/services/bulk_upload/sales/year2024/row_parser_spec.rb b/spec/services/bulk_upload/sales/year2024/row_parser_spec.rb index d93453a22..35a7c38e2 100644 --- a/spec/services/bulk_upload/sales/year2024/row_parser_spec.rb +++ b/spec/services/bulk_upload/sales/year2024/row_parser_spec.rb @@ -103,7 +103,7 @@ RSpec.describe BulkUpload::Sales::Year2024::RowParser do field_101: "250000", field_102: "25", field_103: "1", - field_104: "42500", + field_104: "5000", field_105: "1", field_107: "20", field_108: "3",