diff --git a/app/models/validations/sales/sale_information_validations.rb b/app/models/validations/sales/sale_information_validations.rb index be0295f2c..c42c42ccc 100644 --- a/app/models/validations/sales/sale_information_validations.rb +++ b/app/models/validations/sales/sale_information_validations.rb @@ -38,4 +38,20 @@ module Validations::Sales::SaleInformationValidations record.errors.add :fromprop, I18n.t("validations.sale_information.previous_property_type.property_type_bedsit") end end + + def validate_discounted_ownership_value(record) + return unless record.value && record.deposit && record.ownershipsch + return unless record.mortgage || record.mortgageused == 2 + return unless record.discount || record.grant || record.type == 29 + + discount_amount = record.discount ? record.value * record.discount / 100 : 0 + grant_amount = record.grant || 0 + mortgage_amount = record.mortgage || 0 + value_with_discount = (record.value - discount_amount) + if mortgage_amount + record.deposit + grant_amount != value_with_discount && record.discounted_ownership_sale? + %i[mortgage deposit grant value discount ownershipsch].each do |field| + record.errors.add field, I18n.t("validations.sale_information.discounted_ownership_value", value_with_discount: sprintf("%.2f", value_with_discount)) + end + end + end end diff --git a/config/locales/en.yml b/config/locales/en.yml index 0be594420..3dd612e8e 100644 --- a/config/locales/en.yml +++ b/config/locales/en.yml @@ -425,6 +425,7 @@ en: property_type_bedsit: "Bedsit bedroom maximum 1" previous_property_type: property_type_bedsit: "A bedsit can not have more than 1 bedroom" + discounted_ownership_value: "Mortgage, deposit, and grant total must equal £%{value_with_discount}" soft_validations: net_income: diff --git a/spec/factories/sales_log.rb b/spec/factories/sales_log.rb index 003b11144..f83d102d3 100644 --- a/spec/factories/sales_log.rb +++ b/spec/factories/sales_log.rb @@ -70,10 +70,10 @@ FactoryBot.define do ecstat5 { 2 } ecstat6 { 1 } disabled { 1 } - deposit { 10_000 } + deposit { 80_000 } cashdis { 1_000 } value { 110_000 } - grant { 1_000 } + grant { 10_000 } proplen { 10 } pregyrha { 1 } pregla { 1 } diff --git a/spec/models/validations/sales/sale_information_validations_spec.rb b/spec/models/validations/sales/sale_information_validations_spec.rb index fb3aea06c..d2921e8f0 100644 --- a/spec/models/validations/sales/sale_information_validations_spec.rb +++ b/spec/models/validations/sales/sale_information_validations_spec.rb @@ -218,4 +218,157 @@ RSpec.describe Validations::Sales::SaleInformationValidations do end end end + + describe "#validate_discounted_ownership_value" do + context "when grant is routed to" do + let(:record) { FactoryBot.build(:sales_log, mortgage: 10_000, deposit: 5_000, value: 30_000, ownershipsch: 2, type: 8) } + + context "and not provided" do + before do + record.grant = nil + end + + it "does not add an error" do + sale_information_validator.validate_discounted_ownership_value(record) + + expect(record.errors).to be_empty + end + end + + context "and is provided" do + it "adds an error if mortgage, deposit and grant total does not equal market value" do + record.grant = 3_000 + sale_information_validator.validate_discounted_ownership_value(record) + expect(record.errors[:mortgage]).to include(I18n.t("validations.sale_information.discounted_ownership_value", value_with_discount: "30000.00")) + expect(record.errors[:deposit]).to include(I18n.t("validations.sale_information.discounted_ownership_value", value_with_discount: "30000.00")) + expect(record.errors[:grant]).to include(I18n.t("validations.sale_information.discounted_ownership_value", value_with_discount: "30000.00")) + expect(record.errors[:value]).to include(I18n.t("validations.sale_information.discounted_ownership_value", value_with_discount: "30000.00")) + expect(record.errors[:discount]).to include(I18n.t("validations.sale_information.discounted_ownership_value", value_with_discount: "30000.00")) + end + + it "does not add an error if mortgage, deposit and grant total equals market value" do + record.grant = 15_000 + sale_information_validator.validate_discounted_ownership_value(record) + expect(record.errors).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) } + + context "and not provided" do + before do + record.discount = nil + end + + it "does not add an error" do + sale_information_validator.validate_discounted_ownership_value(record) + + expect(record.errors).to be_empty + end + end + + context "and is provided" do + it "adds an error 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[:mortgage]).to include(I18n.t("validations.sale_information.discounted_ownership_value", value_with_discount: "27000.00")) + expect(record.errors[:deposit]).to include(I18n.t("validations.sale_information.discounted_ownership_value", value_with_discount: "27000.00")) + expect(record.errors[:grant]).to include(I18n.t("validations.sale_information.discounted_ownership_value", value_with_discount: "27000.00")) + expect(record.errors[:value]).to include(I18n.t("validations.sale_information.discounted_ownership_value", value_with_discount: "27000.00")) + expect(record.errors[:discount]).to include(I18n.t("validations.sale_information.discounted_ownership_value", value_with_discount: "27000.00")) + end + + it "does not add an error if mortgage and deposit total equals market value - discount" do + record.discount = 50 + sale_information_validator.validate_discounted_ownership_value(record) + expect(record.errors).to be_empty + end + 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) } + + it "adds an error 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[:mortgage]).to include(I18n.t("validations.sale_information.discounted_ownership_value", value_with_discount: "30000.00")) + expect(record.errors[:deposit]).to include(I18n.t("validations.sale_information.discounted_ownership_value", value_with_discount: "30000.00")) + expect(record.errors[:grant]).to include(I18n.t("validations.sale_information.discounted_ownership_value", value_with_discount: "30000.00")) + expect(record.errors[:value]).to include(I18n.t("validations.sale_information.discounted_ownership_value", value_with_discount: "30000.00")) + expect(record.errors[:discount]).to include(I18n.t("validations.sale_information.discounted_ownership_value", value_with_discount: "30000.00")) + end + + it "does not add an error if mortgage and deposit total equals market value" do + record.deposit = 20_000 + sale_information_validator.validate_discounted_ownership_value(record) + expect(record.errors).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) } + + context "and not provided" do + before do + record.mortgage = nil + end + + it "does not add an error" do + sale_information_validator.validate_discounted_ownership_value(record) + + expect(record.errors).to be_empty + end + end + + context "and is provided" do + it "adds an error 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[:mortgage]).to include(I18n.t("validations.sale_information.discounted_ownership_value", value_with_discount: "18000.00")) + expect(record.errors[:deposit]).to include(I18n.t("validations.sale_information.discounted_ownership_value", value_with_discount: "18000.00")) + expect(record.errors[:grant]).to include(I18n.t("validations.sale_information.discounted_ownership_value", value_with_discount: "18000.00")) + expect(record.errors[:value]).to include(I18n.t("validations.sale_information.discounted_ownership_value", value_with_discount: "18000.00")) + expect(record.errors[:discount]).to include(I18n.t("validations.sale_information.discounted_ownership_value", value_with_discount: "18000.00")) + end + + it "does not add an error 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).to be_empty + end + 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) } + + it "adds an error if grant and deposit total does not equal market value - discount" do + sale_information_validator.validate_discounted_ownership_value(record) + expect(record.errors[:mortgage]).to include(I18n.t("validations.sale_information.discounted_ownership_value", value_with_discount: "18000.00")) + expect(record.errors[:deposit]).to include(I18n.t("validations.sale_information.discounted_ownership_value", value_with_discount: "18000.00")) + expect(record.errors[:grant]).to include(I18n.t("validations.sale_information.discounted_ownership_value", value_with_discount: "18000.00")) + expect(record.errors[:value]).to include(I18n.t("validations.sale_information.discounted_ownership_value", value_with_discount: "18000.00")) + expect(record.errors[:discount]).to include(I18n.t("validations.sale_information.discounted_ownership_value", value_with_discount: "18000.00")) + end + + it "does not add an error 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).to be_empty + end + end + + context "when owhership 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) } + + it "does not add an error" do + sale_information_validator.validate_discounted_ownership_value(record) + + expect(record.errors).to be_empty + end + end + end end