diff --git a/app/models/form/sales/pages/about_deposit_with_discount.rb b/app/models/form/sales/pages/about_deposit_with_discount.rb index 5d1e41a95..4f1eed451 100644 --- a/app/models/form/sales/pages/about_deposit_with_discount.rb +++ b/app/models/form/sales/pages/about_deposit_with_discount.rb @@ -14,9 +14,9 @@ class Form::Sales::Pages::AboutDepositWithDiscount < ::Form::Page def depends_on if form.start_year_after_2024? - [{ "is_type_discount?" => true, "stairowned_100?" => @optional }] + [{ "social_homebuy?" => true, "stairowned_100?" => @optional }] else - [{ "is_type_discount?" => true }] + [{ "social_homebuy?" => true }] end end end diff --git a/app/models/form/sales/pages/about_deposit_without_discount.rb b/app/models/form/sales/pages/about_deposit_without_discount.rb index fdd74cf31..5747c3ed4 100644 --- a/app/models/form/sales/pages/about_deposit_without_discount.rb +++ b/app/models/form/sales/pages/about_deposit_without_discount.rb @@ -14,11 +14,11 @@ class Form::Sales::Pages::AboutDepositWithoutDiscount < ::Form::Page def depends_on if form.start_year_after_2024? - [{ "is_type_discount?" => false, "ownershipsch" => 1, "stairowned_100?" => @optional }, + [{ "social_homebuy?" => false, "ownershipsch" => 1, "stairowned_100?" => @optional }, { "ownershipsch" => 2 }, { "ownershipsch" => 3, "mortgageused" => 1 }] else - [{ "is_type_discount?" => false, "ownershipsch" => 1 }, + [{ "social_homebuy?" => false, "ownershipsch" => 1 }, { "ownershipsch" => 2 }, { "ownershipsch" => 3, "mortgageused" => 1 }] end diff --git a/app/models/sales_log.rb b/app/models/sales_log.rb index f35393a51..5223c249b 100644 --- a/app/models/sales_log.rb +++ b/app/models/sales_log.rb @@ -239,7 +239,7 @@ class SalesLog < Log ownershipsch == 3 || (ownershipsch == 2 && rent_to_buy_full_ownership?) end - def is_type_discount? + def social_homebuy? type == 18 end @@ -287,6 +287,13 @@ class SalesLog < Log mortgage_amount + deposit_amount + cashdis_amount end + def deposit_and_discount_total + deposit_amount = deposit || 0 + cashdis_amount = cashdis || 0 + + deposit_amount + cashdis_amount + end + def value_times_equity return unless value && equity diff --git a/app/models/validations/sales/financial_validations.rb b/app/models/validations/sales/financial_validations.rb index 6b36091ac..3e1d3dfb8 100644 --- a/app/models/validations/sales/financial_validations.rb +++ b/app/models/validations/sales/financial_validations.rb @@ -102,23 +102,6 @@ module Validations::Sales::FinancialValidations end end - def validate_shared_ownership_deposit(record) - return unless record.saledate && record.form.start_year_after_2024? - return unless record.mortgage || record.mortgageused == 2 || record.mortgageused == 3 - return unless record.cashdis && record.deposit && record.value && record.equity - - mortgage_value = record.mortgage || 0 - - if mortgage_value + record.deposit + record.cashdis != record.value * record.equity / 100 - %i[mortgage value deposit ownershipsch cashdis equity].each do |field| - record.errors.add field, I18n.t("validations.financial.shared_ownership_deposit", - mortgage_deposit_and_discount_error_fields: record.mortgage_deposit_and_discount_error_fields, - mortgage_deposit_and_discount_total: record.field_formatted_as_currency("mortgage_deposit_and_discount_total"), - value_times_equity: record.field_formatted_as_currency("value_times_equity")) - end - end - end - def validate_equity_less_than_staircase_difference(record) return unless record.equity && record.stairbought && record.stairowned return unless record.saledate && record.form.start_year_after_2024? diff --git a/app/models/validations/sales/sale_information_validations.rb b/app/models/validations/sales/sale_information_validations.rb index 883e10d1d..81054e830 100644 --- a/app/models/validations/sales/sale_information_validations.rb +++ b/app/models/validations/sales/sale_information_validations.rb @@ -107,53 +107,115 @@ module Validations::Sales::SaleInformationValidations end def validate_non_staircasing_mortgage(record) + return unless record.saledate && record.form.start_year_after_2024? return unless record.value && record.deposit && record.equity - return unless record.is_not_staircasing? + return unless record.shared_ownership_scheme? && record.type && record.mortgageused && record.is_not_staircasing? + + if record.social_homebuy? + check_non_staircasing_socialhomebuy_mortgage(record) + else + check_non_staircasing_non_socialhomebuy_mortgage(record) + end + end + + def validate_staircasing_mortgage(record) return unless record.saledate && record.form.start_year_after_2024? + return unless record.value && record.deposit && record.stairbought + return unless record.shared_ownership_scheme? && record.type && record.mortgageused && record.is_staircase? + + if record.social_homebuy? + check_staircasing_socialhomebuy_mortgage(record) + else + check_staircasing_non_socialhomebuy_mortgage(record) + end + end + + def validate_mortgage_used_and_stairbought(record) + return unless record.stairowned && record.mortgageused + + if !record.stairowned_100? && record.mortgageused == 3 + record.errors.add :stairowned, I18n.t("validations.sale_information.stairowned.mortgageused_dont_know") + record.errors.add :mortgageused, I18n.t("validations.sale_information.stairowned.mortgageused_dont_know") + end + end + + def check_non_staircasing_socialhomebuy_mortgage(record) + return unless record.cashdis + + if record.mortgage_used? + return unless record.mortgage + + if over_tolerance?(record.mortgage_deposit_and_discount_total, record.expected_shared_ownership_deposit_value, 1) + %i[mortgage value deposit cashdis equity].each do |field| + record.errors.add field, I18n.t("validations.sale_information.non_staircasing_mortgage.mortgage_used_socialhomebuy", mortgage_deposit_and_discount_total: record.field_formatted_as_currency("mortgage_deposit_and_discount_total"), expected_shared_ownership_deposit_value: record.field_formatted_as_currency("expected_shared_ownership_deposit_value")) + end + record.errors.add :type, :skip_bu_error, message: I18n.t("validations.sale_information.non_staircasing_mortgage.mortgage_used_socialhomebuy", mortgage_deposit_and_discount_total: record.field_formatted_as_currency("mortgage_deposit_and_discount_total"), expected_shared_ownership_deposit_value: record.field_formatted_as_currency("expected_shared_ownership_deposit_value")) + end + elsif record.mortgage_not_used? + if over_tolerance?(record.deposit_and_discount_total, record.expected_shared_ownership_deposit_value, 1) + %i[mortgageused value deposit cashdis equity].each do |field| + record.errors.add field, I18n.t("validations.sale_information.non_staircasing_mortgage.mortgage_not_used_socialhomebuy", deposit_and_discount_total: record.field_formatted_as_currency("deposit_and_discount_total"), expected_shared_ownership_deposit_value: record.field_formatted_as_currency("expected_shared_ownership_deposit_value")) + end + record.errors.add :type, :skip_bu_error, message: I18n.t("validations.sale_information.non_staircasing_mortgage.mortgage_not_used_socialhomebuy", deposit_and_discount_total: record.field_formatted_as_currency("deposit_and_discount_total"), expected_shared_ownership_deposit_value: record.field_formatted_as_currency("expected_shared_ownership_deposit_value")) + end + end + end + def check_non_staircasing_non_socialhomebuy_mortgage(record) if record.mortgage_used? return unless record.mortgage - if record.mortgage_and_deposit_total != record.expected_shared_ownership_deposit_value + if over_tolerance?(record.mortgage_and_deposit_total, record.expected_shared_ownership_deposit_value, 1) %i[mortgage value deposit equity].each do |field| record.errors.add field, I18n.t("validations.sale_information.non_staircasing_mortgage.mortgage_used", mortgage_and_deposit_total: record.field_formatted_as_currency("mortgage_and_deposit_total"), expected_shared_ownership_deposit_value: record.field_formatted_as_currency("expected_shared_ownership_deposit_value")) end + record.errors.add :type, :skip_bu_error, message: I18n.t("validations.sale_information.non_staircasing_mortgage.mortgage_used", mortgage_and_deposit_total: record.field_formatted_as_currency("mortgage_and_deposit_total"), expected_shared_ownership_deposit_value: record.field_formatted_as_currency("expected_shared_ownership_deposit_value")) end elsif record.mortgage_not_used? - if record.deposit != record.expected_shared_ownership_deposit_value + if over_tolerance?(record.deposit, record.expected_shared_ownership_deposit_value, 1) %i[mortgageused value deposit equity].each do |field| record.errors.add field, I18n.t("validations.sale_information.non_staircasing_mortgage.mortgage_not_used", deposit: record.field_formatted_as_currency("deposit"), expected_shared_ownership_deposit_value: record.field_formatted_as_currency("expected_shared_ownership_deposit_value")) end + record.errors.add :type, :skip_bu_error, message: I18n.t("validations.sale_information.non_staircasing_mortgage.mortgage_not_used", deposit: record.field_formatted_as_currency("deposit"), expected_shared_ownership_deposit_value: record.field_formatted_as_currency("expected_shared_ownership_deposit_value")) end 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? + def check_staircasing_socialhomebuy_mortgage(record) + return unless record.cashdis 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")) + if over_tolerance?(record.mortgage_deposit_and_discount_total, record.stairbought_part_of_value, 1) + %i[mortgage value deposit cashdis stairbought].each do |field| + record.errors.add field, I18n.t("validations.sale_information.staircasing_mortgage.mortgage_used_socialhomebuy", mortgage_deposit_and_discount_total: record.field_formatted_as_currency("mortgage_deposit_and_discount_total"), stairbought_part_of_value: record.field_formatted_as_currency("stairbought_part_of_value")) end + record.errors.add :type, :skip_bu_error, message: I18n.t("validations.sale_information.staircasing_mortgage.mortgage_used_socialhomebuy", mortgage_deposit_and_discount_total: record.field_formatted_as_currency("mortgage_deposit_and_discount_total"), stairbought_part_of_value: record.field_formatted_as_currency("stairbought_part_of_value")) 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")) + elsif over_tolerance?(record.deposit_and_discount_total, record.stairbought_part_of_value, 1) + %i[mortgageused value deposit cashdis stairbought].each do |field| + record.errors.add field, I18n.t("validations.sale_information.staircasing_mortgage.mortgage_not_used_socialhomebuy", deposit_and_discount_total: record.field_formatted_as_currency("deposit_and_discount_total"), stairbought_part_of_value: record.field_formatted_as_currency("stairbought_part_of_value")) end + record.errors.add :type, :skip_bu_error, message: I18n.t("validations.sale_information.staircasing_mortgage.mortgage_not_used_socialhomebuy", deposit_and_discount_total: record.field_formatted_as_currency("deposit_and_discount_total"), stairbought_part_of_value: record.field_formatted_as_currency("stairbought_part_of_value")) end end - def validate_mortgage_used_and_stairbought(record) - return unless record.stairowned && record.mortgageused + def check_staircasing_non_socialhomebuy_mortgage(record) + if record.mortgage_used? + return unless record.mortgage - if !record.stairowned_100? && record.mortgageused == 3 - record.errors.add :stairowned, I18n.t("validations.sale_information.stairowned.mortgageused_dont_know") - record.errors.add :mortgageused, I18n.t("validations.sale_information.stairowned.mortgageused_dont_know") + if over_tolerance?(record.mortgage_and_deposit_total, record.stairbought_part_of_value, 1) + %i[mortgage value deposit stairbought type].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 + record.errors.add :type, :skip_bu_error, message: 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 + elsif over_tolerance?(record.deposit, record.stairbought_part_of_value, 1) + %i[mortgageused value deposit stairbought type].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 + record.errors.add :type, :skip_bu_error, message: 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 @@ -170,4 +232,8 @@ module Validations::Sales::SaleInformationValidations record.errors.add(:mortgageused, I18n.t("validations.invalid_option", question: "Was a mortgage used for the purchase of this property?")) end end + + def over_tolerance?(expected, actual, tolerance) + (expected - actual).abs >= tolerance + end end diff --git a/app/models/validations/sales/soft_validations.rb b/app/models/validations/sales/soft_validations.rb index 14c0afae4..51326a2f4 100644 --- a/app/models/validations/sales/soft_validations.rb +++ b/app/models/validations/sales/soft_validations.rb @@ -1,4 +1,6 @@ module Validations::Sales::SoftValidations + include Validations::Sales::SaleInformationValidations + ALLOWED_INCOME_RANGES_SALES = { 1 => OpenStruct.new(soft_min: 5000), 2 => OpenStruct.new(soft_min: 1500), @@ -86,14 +88,10 @@ module Validations::Sales::SoftValidations def shared_ownership_deposit_invalid? return unless saledate && collection_start_year <= 2023 return unless mortgage || mortgageused == 2 || mortgageused == 3 - return unless cashdis || !is_type_discount? + return unless cashdis || !social_homebuy? return unless deposit && value && equity - !within_tolerance?(mortgage_deposit_and_discount_total, value * equity / 100, 1) - end - - def within_tolerance?(expected, actual, tolerance) - (expected - actual).abs <= tolerance + over_tolerance?(mortgage_deposit_and_discount_total, value * equity / 100, 1) end def mortgage_plus_deposit_less_than_discounted_value? diff --git a/app/services/bulk_upload/sales/year2024/row_parser.rb b/app/services/bulk_upload/sales/year2024/row_parser.rb index f1124f79d..87d6b491c 100644 --- a/app/services/bulk_upload/sales/year2024/row_parser.rb +++ b/app/services/bulk_upload/sales/year2024/row_parser.rb @@ -513,6 +513,7 @@ class BulkUpload::Sales::Year2024::RowParser fields.each do |field| next if errors.include?(field) + next if error.type == :skip_bu_error question = log.form.get_question(error.attribute, log) @@ -721,16 +722,16 @@ private lanomagr: %i[field_97], frombeds: %i[field_98], fromprop: %i[field_99], - value: %i[field_101 field_114 field_125], + value: value_fields, equity: %i[field_102], - mortgage: %i[field_104 field_118 field_127], - extrabor: %i[field_108 field_122 field_129], - deposit: %i[field_109 field_123 field_130], + mortgage: mortgage_fields, + extrabor: extrabor_fields, + deposit: deposit_fields, cashdis: %i[field_110], mrent: %i[field_111], - has_mscharge: %i[field_112 field_124 field_131], - mscharge: %i[field_112 field_124 field_131], + has_mscharge: mscharge_fields, + mscharge: mscharge_fields, grant: %i[field_115], discount: %i[field_116], othtype: %i[field_12], @@ -741,12 +742,12 @@ private hhregresstill: %i[field_73], armedforcesspouse: %i[field_74], - mortgagelender: %i[field_105 field_119], - mortgagelenderother: %i[field_106 field_120], + mortgagelender: mortgagelender_fields, + mortgagelenderother: mortgagelenderother_fields, hb: %i[field_81], - mortlen: %i[field_107 field_121 field_128], - proplen: %i[field_113 field_85], + mortlen: mortlen_fields, + proplen: proplen_fields, jointmore: %i[field_16], staircase: %i[field_86], @@ -762,7 +763,7 @@ private stairbought: %i[field_87], stairowned: %i[field_88], socprevten: %i[field_100], - mortgageused: [mortgageused_field], + mortgageused: mortgageused_fields, uprn: %i[field_22], address_line1: %i[field_23], @@ -1118,10 +1119,81 @@ private return field_126 if outright_sale? end - def mortgageused_field - return :field_103 if shared_ownership? - return :field_117 if discounted_ownership? - return :field_126 if outright_sale? + def value_fields + return [:field_101] if shared_ownership? + return [:field_114] if discounted_ownership? + return [:field_125] if outright_sale? + + %i[field_101 field_114 field_125] + end + + def mortgage_fields + return [:field_104] if shared_ownership? + return [:field_118] if discounted_ownership? + return [:field_127] if outright_sale? + + %i[field_104 field_118 field_127] + end + + def extrabor_fields + return [:field_108] if shared_ownership? + return [:field_122] if discounted_ownership? + return [:field_129] if outright_sale? + + %i[field_108 field_122 field_129] + end + + def deposit_fields + return [:field_109] if shared_ownership? + return [:field_123] if discounted_ownership? + return [:field_130] if outright_sale? + + %i[field_109 field_123 field_130] + end + + def mscharge_fields + return [:field_112] if shared_ownership? + return [:field_124] if discounted_ownership? + return [:field_131] if outright_sale? + + %i[field_112 field_124 field_131] + end + + def mortgagelender_fields + return [:field_105] if shared_ownership? + return [:field_119] if discounted_ownership? + + %i[field_105 field_119] + end + + def mortgagelenderother_fields + return [:field_106] if shared_ownership? + return [:field_120] if discounted_ownership? + + %i[field_106 field_120] + end + + def mortlen_fields + return [:field_107] if shared_ownership? + return [:field_121] if discounted_ownership? + return [:field_128] if outright_sale? + + %i[field_107 field_121 field_128] + end + + def proplen_fields + return [:field_85] if shared_ownership? + return [:field_113] if discounted_ownership? + + %i[field_85 field_113] + end + + def mortgageused_fields + return [:field_103] if shared_ownership? + return [:field_117] if discounted_ownership? + return [:field_126] if outright_sale? + + %i[field_103 field_117 field_126] end def owning_organisation diff --git a/config/locales/en.yml b/config/locales/en.yml index afbba3e2c..2f3e63020 100644 --- a/config/locales/en.yml +++ b/config/locales/en.yml @@ -641,11 +641,15 @@ en: over_discounted_london_max: "The percentage discount multiplied by the purchase price is %{discount_value}. This figure should not be more than £136,400 for properties in London." over_discounted_max: "The percentage discount multiplied by the purchase price is %{discount_value}. This figure should not be more than £102,400 for properties outside of London." 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." + mortgage_used: "The mortgage and deposit added together is %{mortgage_and_deposit_total}. The value multiplied by the percentage bought is %{expected_shared_ownership_deposit_value}. These figures should be the same." + mortgage_not_used: "The deposit is %{deposit} and the value multiplied by the percentage bought is %{expected_shared_ownership_deposit_value}. These figures should be the same." + mortgage_used_socialhomebuy: "The mortgage, deposit, and cash discount added together is %{mortgage_deposit_and_discount_total}. The value multiplied by the percentage bought is %{expected_shared_ownership_deposit_value}. These figures should be the same." + mortgage_not_used_socialhomebuy: "The deposit and cash discount added together is %{deposit_and_discount_total}. The value multiplied by the percentage bought is %{expected_shared_ownership_deposit_value}. 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." + mortgage_used: "The mortgage and deposit added together is %{mortgage_and_deposit_total}. The value multiplied by the percentage bought is %{stairbought_part_of_value}. These figures should be the same." + mortgage_not_used: "The deposit is %{deposit} and the value multiplied by the percentage bought is %{stairbought_part_of_value}. These figures should be the same." + mortgage_used_socialhomebuy: "The mortgage, deposit, and cash discount added together is %{mortgage_deposit_and_discount_total}. The value multiplied by the percentage bought is %{stairbought_part_of_value}. These figures should be the same." + mortgage_not_used_socialhomebuy: "The deposit and cash discount added together is %{deposit_and_discount_total}. The value multiplied by the percentage bought is %{stairbought_part_of_value}. 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/form/sales/pages/about_deposit_with_discount_spec.rb b/spec/models/form/sales/pages/about_deposit_with_discount_spec.rb index 4cffb2b54..fabfb7836 100644 --- a/spec/models/form/sales/pages/about_deposit_with_discount_spec.rb +++ b/spec/models/form/sales/pages/about_deposit_with_discount_spec.rb @@ -33,7 +33,7 @@ RSpec.describe Form::Sales::Pages::AboutDepositWithDiscount, type: :model do it "has correct depends_on" do expect(page.depends_on).to eq( - [{ "is_type_discount?" => true }], + [{ "social_homebuy?" => true }], ) end @@ -42,7 +42,7 @@ RSpec.describe Form::Sales::Pages::AboutDepositWithDiscount, type: :model do it "has correct depends_on" do expect(page.depends_on).to eq( - [{ "is_type_discount?" => true }], + [{ "social_homebuy?" => true }], ) end end @@ -54,7 +54,7 @@ RSpec.describe Form::Sales::Pages::AboutDepositWithDiscount, type: :model do it "has correct depends_on" do expect(page.depends_on).to eq( - [{ "is_type_discount?" => true, "stairowned_100?" => false }], + [{ "social_homebuy?" => true, "stairowned_100?" => false }], ) end @@ -63,7 +63,7 @@ RSpec.describe Form::Sales::Pages::AboutDepositWithDiscount, type: :model do it "has correct depends_on" do expect(page.depends_on).to eq( - [{ "is_type_discount?" => true, "stairowned_100?" => true }], + [{ "social_homebuy?" => true, "stairowned_100?" => true }], ) end end diff --git a/spec/models/form/sales/pages/about_deposit_without_discount_spec.rb b/spec/models/form/sales/pages/about_deposit_without_discount_spec.rb index d6f58c65f..003313353 100644 --- a/spec/models/form/sales/pages/about_deposit_without_discount_spec.rb +++ b/spec/models/form/sales/pages/about_deposit_without_discount_spec.rb @@ -33,7 +33,7 @@ RSpec.describe Form::Sales::Pages::AboutDepositWithoutDiscount, type: :model do it "has correct depends_on" do expect(page.depends_on).to eq( - [{ "is_type_discount?" => false, "ownershipsch" => 1 }, + [{ "social_homebuy?" => false, "ownershipsch" => 1 }, { "ownershipsch" => 2 }, { "ownershipsch" => 3, "mortgageused" => 1 }], ) @@ -44,7 +44,7 @@ RSpec.describe Form::Sales::Pages::AboutDepositWithoutDiscount, type: :model do it "has correct depends_on" do expect(page.depends_on).to eq( - [{ "is_type_discount?" => false, "ownershipsch" => 1 }, + [{ "social_homebuy?" => false, "ownershipsch" => 1 }, { "ownershipsch" => 2 }, { "ownershipsch" => 3, "mortgageused" => 1 }], ) @@ -58,7 +58,7 @@ RSpec.describe Form::Sales::Pages::AboutDepositWithoutDiscount, type: :model do it "has correct depends_on" do expect(page.depends_on).to eq( - [{ "is_type_discount?" => false, "ownershipsch" => 1, "stairowned_100?" => false }, + [{ "social_homebuy?" => false, "ownershipsch" => 1, "stairowned_100?" => false }, { "ownershipsch" => 2 }, { "ownershipsch" => 3, "mortgageused" => 1 }], ) @@ -69,7 +69,7 @@ RSpec.describe Form::Sales::Pages::AboutDepositWithoutDiscount, type: :model do it "has correct depends_on" do expect(page.depends_on).to eq( - [{ "is_type_discount?" => false, "ownershipsch" => 1, "stairowned_100?" => true }, + [{ "social_homebuy?" => false, "ownershipsch" => 1, "stairowned_100?" => true }, { "ownershipsch" => 2 }, { "ownershipsch" => 3, "mortgageused" => 1 }], ) diff --git a/spec/models/validations/sales/financial_validations_spec.rb b/spec/models/validations/sales/financial_validations_spec.rb index e52387987..316c2d175 100644 --- a/spec/models/validations/sales/financial_validations_spec.rb +++ b/spec/models/validations/sales/financial_validations_spec.rb @@ -432,181 +432,6 @@ RSpec.describe Validations::Sales::FinancialValidations do end end - describe "#validate_shared_ownership_deposit" do - let(:record) { FactoryBot.create(:sales_log, saledate: now) } - - around do |example| - Timecop.freeze(now) do - Singleton.__init__(FormHandler) - example.run - end - Timecop.return - end - - context "with a log in the 24/25 collection year" do - let(:now) { Time.zone.local(2024, 4, 2) } - - it "does not add an error if MORTGAGE + DEPOSIT + CASHDIS are equal VALUE * EQUITY/100" do - record.mortgage = 1000 - record.deposit = 1000 - record.cashdis = 1000 - record.value = 3000 - record.equity = 100 - - financial_validator.validate_shared_ownership_deposit(record) - expect(record.errors["mortgage"]).to be_empty - expect(record.errors["deposit"]).to be_empty - expect(record.errors["cashdis"]).to be_empty - expect(record.errors["value"]).to be_empty - expect(record.errors["equity"]).to be_empty - end - - it "does not add an error if mortgage is used and no mortgage is given" do - record.mortgage = nil - record.deposit = 1000 - record.cashdis = 1000 - record.value = 3000 - record.equity = 100 - - financial_validator.validate_shared_ownership_deposit(record) - expect(record.errors["mortgage"]).to be_empty - expect(record.errors["deposit"]).to be_empty - expect(record.errors["cashdis"]).to be_empty - expect(record.errors["value"]).to be_empty - expect(record.errors["equity"]).to be_empty - end - - it "adds an error if mortgage is not used and no mortgage is given" do - record.mortgage = nil - record.mortgageused = 2 - record.deposit = 1000 - record.cashdis = 1000 - record.value = 3000 - record.equity = 100 - - financial_validator.validate_shared_ownership_deposit(record) - expect(record.errors["mortgage"]).to include("The mortgage, deposit, and cash discount added together is £2,000.00. The value times the equity percentage is £3,000.00. These figures should be the same") - expect(record.errors["deposit"]).to include("The mortgage, deposit, and cash discount added together is £2,000.00. The value times the equity percentage is £3,000.00. These figures should be the same") - expect(record.errors["cashdis"]).to include("The mortgage, deposit, and cash discount added together is £2,000.00. The value times the equity percentage is £3,000.00. These figures should be the same") - expect(record.errors["value"]).to include("The mortgage, deposit, and cash discount added together is £2,000.00. The value times the equity percentage is £3,000.00. These figures should be the same") - expect(record.errors["equity"]).to include("The mortgage, deposit, and cash discount added together is £2,000.00. The value times the equity percentage is £3,000.00. These figures should be the same") - end - - it "does not add an error if no deposit is given" do - record.mortgage = 1000 - record.deposit = nil - record.cashdis = 1000 - record.value = 3000 - record.equity = 100 - - financial_validator.validate_shared_ownership_deposit(record) - expect(record.errors["mortgage"]).to be_empty - expect(record.errors["deposit"]).to be_empty - expect(record.errors["cashdis"]).to be_empty - expect(record.errors["value"]).to be_empty - expect(record.errors["equity"]).to be_empty - end - - it "does not add an error if no cashdis is given and cashdis is routed to" do - record.mortgage = 1000 - record.deposit = 1000 - record.type = 18 - record.cashdis = nil - record.value = 3000 - record.equity = 100 - - financial_validator.validate_shared_ownership_deposit(record) - expect(record.errors["mortgage"]).to be_empty - expect(record.errors["deposit"]).to be_empty - expect(record.errors["cashdis"]).to be_empty - expect(record.errors["value"]).to be_empty - expect(record.errors["equity"]).to be_empty - end - - it "does not add an error if no cashdis is given and cashdis is not routed to" do - record.mortgageused = 1 - record.mortgage = 1000 - record.deposit = 1000 - record.type = 2 - record.cashdis = nil - record.value = 3000 - record.equity = 100 - - financial_validator.validate_shared_ownership_deposit(record) - expect(record.errors["mortgage"]).to be_empty - expect(record.errors["deposit"]).to be_empty - expect(record.errors["cashdis"]).to be_empty - expect(record.errors["value"]).to be_empty - expect(record.errors["equity"]).to be_empty - end - - it "does not add an error if no value is given" do - record.mortgage = 1000 - record.deposit = 1000 - record.cashdis = 1000 - record.value = nil - record.equity = 100 - - financial_validator.validate_shared_ownership_deposit(record) - expect(record.errors["mortgage"]).to be_empty - expect(record.errors["deposit"]).to be_empty - expect(record.errors["cashdis"]).to be_empty - expect(record.errors["value"]).to be_empty - expect(record.errors["equity"]).to be_empty - end - - it "does not add an error if no equity is given" do - record.mortgage = 1000 - record.deposit = 1000 - record.cashdis = 1000 - record.value = 3000 - record.equity = nil - - financial_validator.validate_shared_ownership_deposit(record) - expect(record.errors["mortgage"]).to be_empty - expect(record.errors["deposit"]).to be_empty - expect(record.errors["cashdis"]).to be_empty - expect(record.errors["value"]).to be_empty - expect(record.errors["equity"]).to be_empty - end - - it "adds an error if MORTGAGE + DEPOSIT + CASHDIS are not equal VALUE * EQUITY/100" do - record.mortgageused = 1 - record.mortgage = 1000 - record.deposit = 1000 - record.cashdis = 1000 - record.value = 4323 - record.equity = 100 - - financial_validator.validate_shared_ownership_deposit(record) - expect(record.errors["mortgage"]).to include("The mortgage, deposit, and cash discount added together is £3,000.00. The value times the equity percentage is £4,323.00. These figures should be the same") - expect(record.errors["deposit"]).to include("The mortgage, deposit, and cash discount added together is £3,000.00. The value times the equity percentage is £4,323.00. These figures should be the same") - expect(record.errors["cashdis"]).to include("The mortgage, deposit, and cash discount added together is £3,000.00. The value times the equity percentage is £4,323.00. These figures should be the same") - expect(record.errors["value"]).to include("The mortgage, deposit, and cash discount added together is £3,000.00. The value times the equity percentage is £4,323.00. These figures should be the same") - expect(record.errors["equity"]).to include("The mortgage, deposit, and cash discount added together is £3,000.00. The value times the equity percentage is £4,323.00. These figures should be the same") - end - end - - context "with a log in 23/24 collection year" do - let(:now) { Time.zone.local(2024, 1, 1) } - - it "does not add an error if MORTGAGE + DEPOSIT + CASHDIS are not equal VALUE * EQUITY/100" do - record.mortgage = 1000 - record.deposit = 1000 - record.cashdis = 1000 - record.value = 4323 - record.equity = 100 - - financial_validator.validate_shared_ownership_deposit(record) - expect(record.errors["mortgage"]).to be_empty - expect(record.errors["deposit"]).to be_empty - expect(record.errors["cashdis"]).to be_empty - expect(record.errors["value"]).to be_empty - expect(record.errors["equity"]).to be_empty - end - end - end - describe "#validate_equity_less_than_staircase_difference" do let(:record) { FactoryBot.create(:sales_log, saledate: now) } diff --git a/spec/models/validations/sales/sale_information_validations_spec.rb b/spec/models/validations/sales/sale_information_validations_spec.rb index ca07da6f4..4da297f53 100644 --- a/spec/models/validations/sales/sale_information_validations_spec.rb +++ b/spec/models/validations/sales/sale_information_validations_spec.rb @@ -740,10 +740,45 @@ RSpec.describe Validations::Sales::SaleInformationValidations do it "adds an error" do sale_information_validator.validate_non_staircasing_mortgage(record) - expect(record.errors["mortgage"]).to include("The mortgage and deposit added together is £15,000.00 and the purchase price times by the equity 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 purchase price times by the equity 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 purchase price times by the equity is £8,400.00. These figures should be the same.") - expect(record.errors["equity"]).to include("The mortgage and deposit added together is £15,000.00 and the purchase price times by the equity is £8,400.00. These figures should be the same.") + expect(record.errors["mortgage"]).to include("The mortgage and deposit added together is £15,000.00. The value multiplied by the percentage bought 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. The value multiplied by the percentage bought 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. The value multiplied by the percentage bought is £8,400.00. These figures should be the same.") + expect(record.errors["equity"]).to include("The mortgage and deposit added together is £15,000.00. The value multiplied by the percentage bought is £8,400.00. These figures should be the same.") + expect(record.errors["type"]).to include("The mortgage and deposit added together is £15,000.00. The value multiplied by the percentage bought is £8,400.00. These figures should be the same.") + expect(record.errors["cashdis"]).not_to include("The mortgage and deposit added together is £15,000.00. The value multiplied by the percentage bought is £8,400.00. These figures should be the same.") + end + + context "and it is a social homebuy" do + before do + record.type = 18 + record.cashdis = "200" + end + + it "adds an error" do + sale_information_validator.validate_non_staircasing_mortgage(record) + expect(record.errors["mortgage"]).to include("The mortgage, deposit, and cash discount added together is £15,200.00. The value multiplied by the percentage bought is £8,400.00. These figures should be the same.") + expect(record.errors["value"]).to include("The mortgage, deposit, and cash discount added together is £15,200.00. The value multiplied by the percentage bought is £8,400.00. These figures should be the same.") + expect(record.errors["deposit"]).to include("The mortgage, deposit, and cash discount added together is £15,200.00. The value multiplied by the percentage bought is £8,400.00. These figures should be the same.") + expect(record.errors["equity"]).to include("The mortgage, deposit, and cash discount added together is £15,200.00. The value multiplied by the percentage bought is £8,400.00. These figures should be the same.") + expect(record.errors["cashdis"]).to include("The mortgage, deposit, and cash discount added together is £15,200.00. The value multiplied by the percentage bought is £8,400.00. These figures should be the same.") + expect(record.errors["type"]).to include("The mortgage, deposit, and cash discount added together is £15,200.00. The value multiplied by the percentage bought is £8,400.00. These figures should be the same.") + end + end + + context "and it is not a shared ownership transaction" do + before do + record.ownershipsch = 2 + end + + it "does not add an error" do + sale_information_validator.validate_non_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["equity"]).to be_empty + expect(record.errors["cashdis"]).to be_empty + expect(record.errors["type"]).to be_empty + end end end @@ -758,12 +793,14 @@ RSpec.describe Validations::Sales::SaleInformationValidations do expect(record.errors["value"]).to be_empty expect(record.errors["deposit"]).to be_empty expect(record.errors["equity"]).to be_empty + expect(record.errors["cashdis"]).to be_empty + expect(record.errors["type"]).to be_empty end end end context "when MORTGAGE + DEPOSIT equals VALUE * EQUITY/100" do - let(:record) { FactoryBot.build(:sales_log, mortgage: 10_000, staircase: 2, deposit: 5_000, value: 30_000, equity: 50, ownershipsch: 1, type: 30, saledate: now) } + let(:record) { FactoryBot.build(:sales_log, mortgageused: 1, mortgage: 10_000, staircase: 2, deposit: 5_000, value: 30_000, equity: 50, ownershipsch: 1, type: 30, saledate: now) } it "does not add an error" do sale_information_validator.validate_non_staircasing_mortgage(record) @@ -771,6 +808,22 @@ RSpec.describe Validations::Sales::SaleInformationValidations do expect(record.errors["value"]).to be_empty expect(record.errors["deposit"]).to be_empty expect(record.errors["equity"]).to be_empty + expect(record.errors["cashdis"]).to be_empty + expect(record.errors["type"]).to be_empty + end + end + + context "when MORTGAGE + DEPOSIT is within 1£ tolerance of VALUE * EQUITY/100" do + let(:record) { FactoryBot.build(:sales_log, mortgageused: 1, mortgage: 10_000, staircase: 2, deposit: 50_000, value: 120_001, equity: 50, ownershipsch: 1, type: 30, saledate: now) } + + it "does not add an error" do + sale_information_validator.validate_non_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["equity"]).to be_empty + expect(record.errors["cashdis"]).to be_empty + expect(record.errors["type"]).to be_empty end end @@ -787,10 +840,45 @@ RSpec.describe Validations::Sales::SaleInformationValidations do it "adds an error" do sale_information_validator.validate_non_staircasing_mortgage(record) - expect(record.errors["mortgageused"]).to include("The deposit is £5,000.00 and the purchase price times by the equity 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 purchase price times by the equity 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 purchase price times by the equity is £8,400.00. As no mortgage was used, these figures should be the same.") - expect(record.errors["equity"]).to include("The deposit is £5,000.00 and the purchase price times by the equity is £8,400.00. As no mortgage was used, these figures should be the same.") + expect(record.errors["mortgageused"]).to include("The deposit is £5,000.00 and the value multiplied by the percentage bought is £8,400.00. These figures should be the same.") + expect(record.errors["value"]).to include("The deposit is £5,000.00 and the value multiplied by the percentage bought is £8,400.00. These figures should be the same.") + expect(record.errors["deposit"]).to include("The deposit is £5,000.00 and the value multiplied by the percentage bought is £8,400.00. These figures should be the same.") + expect(record.errors["equity"]).to include("The deposit is £5,000.00 and the value multiplied by the percentage bought is £8,400.00. These figures should be the same.") + expect(record.errors["type"]).to include("The deposit is £5,000.00 and the value multiplied by the percentage bought is £8,400.00. These figures should be the same.") + expect(record.errors["cashdis"]).not_to include("The deposit is £5,000.00 and the value multiplied by the percentage bought is £8,400.00. These figures should be the same.") + end + + context "and it is a social homebuy" do + before do + record.type = 18 + record.cashdis = "200" + end + + it "adds an error" do + sale_information_validator.validate_non_staircasing_mortgage(record) + expect(record.errors["mortgageused"]).to include("The deposit and cash discount added together is £5,200.00. The value multiplied by the percentage bought is £8,400.00. These figures should be the same.") + expect(record.errors["value"]).to include("The deposit and cash discount added together is £5,200.00. The value multiplied by the percentage bought is £8,400.00. These figures should be the same.") + expect(record.errors["deposit"]).to include("The deposit and cash discount added together is £5,200.00. The value multiplied by the percentage bought is £8,400.00. These figures should be the same.") + expect(record.errors["equity"]).to include("The deposit and cash discount added together is £5,200.00. The value multiplied by the percentage bought is £8,400.00. These figures should be the same.") + expect(record.errors["cashdis"]).to include("The deposit and cash discount added together is £5,200.00. The value multiplied by the percentage bought is £8,400.00. These figures should be the same.") + expect(record.errors["type"]).to include("The deposit and cash discount added together is £5,200.00. The value multiplied by the percentage bought is £8,400.00. These figures should be the same.") + end + end + + context "and it is not a shared ownership transaction" do + before do + record.ownershipsch = 2 + end + + it "does not add an error" do + sale_information_validator.validate_non_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["equity"]).to be_empty + expect(record.errors["cashdis"]).to be_empty + expect(record.errors["type"]).to be_empty + end end end @@ -805,6 +893,8 @@ RSpec.describe Validations::Sales::SaleInformationValidations do expect(record.errors["value"]).to be_empty expect(record.errors["deposit"]).to be_empty expect(record.errors["equity"]).to be_empty + expect(record.errors["cashdis"]).to be_empty + expect(record.errors["type"]).to be_empty end end end @@ -818,6 +908,22 @@ RSpec.describe Validations::Sales::SaleInformationValidations do expect(record.errors["value"]).to be_empty expect(record.errors["deposit"]).to be_empty expect(record.errors["equity"]).to be_empty + expect(record.errors["cashdis"]).to be_empty + expect(record.errors["type"]).to be_empty + end + end + + context "when DEPOSIT is within 1£ tolerance of VALUE * EQUITY/100" do + let(:record) { FactoryBot.build(:sales_log, mortgageused: 2, staircase: 2, deposit: 15_000, value: 30_001, equity: 50, ownershipsch: 1, type: 30, saledate: now) } + + it "does not add an error" do + sale_information_validator.validate_non_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["equity"]).to be_empty + expect(record.errors["cashdis"]).to be_empty + expect(record.errors["type"]).to be_empty end end end @@ -833,6 +939,8 @@ RSpec.describe Validations::Sales::SaleInformationValidations do expect(record.errors["value"]).to be_empty expect(record.errors["deposit"]).to be_empty expect(record.errors["equity"]).to be_empty + expect(record.errors["cashdis"]).to be_empty + expect(record.errors["type"]).to be_empty end end end @@ -860,10 +968,45 @@ RSpec.describe Validations::Sales::SaleInformationValidations do 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.") + expect(record.errors["mortgage"]).to include("The mortgage and deposit added together is £15,000.00. The value multiplied by the percentage bought 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. The value multiplied by the percentage bought 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. The value multiplied by the percentage bought 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. The value multiplied by the percentage bought is £8,400.00. These figures should be the same.") + expect(record.errors["type"]).to include("The mortgage and deposit added together is £15,000.00. The value multiplied by the percentage bought is £8,400.00. These figures should be the same.") + expect(record.errors["cashdis"]).not_to include("The mortgage and deposit added together is £15,000.00. The value multiplied by the percentage bought is £8,400.00. These figures should be the same.") + end + + context "and it is a social homebuy" do + before do + record.type = 18 + record.cashdis = "200" + end + + it "adds an error" do + sale_information_validator.validate_staircasing_mortgage(record) + expect(record.errors["mortgage"]).to include("The mortgage, deposit, and cash discount added together is £15,200.00. The value multiplied by the percentage bought is £8,400.00. These figures should be the same.") + expect(record.errors["value"]).to include("The mortgage, deposit, and cash discount added together is £15,200.00. The value multiplied by the percentage bought is £8,400.00. These figures should be the same.") + expect(record.errors["deposit"]).to include("The mortgage, deposit, and cash discount added together is £15,200.00. The value multiplied by the percentage bought is £8,400.00. These figures should be the same.") + expect(record.errors["stairbought"]).to include("The mortgage, deposit, and cash discount added together is £15,200.00. The value multiplied by the percentage bought is £8,400.00. These figures should be the same.") + expect(record.errors["cashdis"]).to include("The mortgage, deposit, and cash discount added together is £15,200.00. The value multiplied by the percentage bought is £8,400.00. These figures should be the same.") + expect(record.errors["type"]).to include("The mortgage, deposit, and cash discount added together is £15,200.00. The value multiplied by the percentage bought is £8,400.00. These figures should be the same.") + end + end + + context "and it is not a shared ownership transaction" do + before do + record.ownershipsch = 2 + end + + it "does not add an error" do + sale_information_validator.validate_non_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 + expect(record.errors["cashdis"]).to be_empty + expect(record.errors["type"]).to be_empty + end end end @@ -878,12 +1021,14 @@ RSpec.describe Validations::Sales::SaleInformationValidations do expect(record.errors["value"]).to be_empty expect(record.errors["deposit"]).to be_empty expect(record.errors["stairbought"]).to be_empty + expect(record.errors["cashdis"]).to be_empty + expect(record.errors["type"]).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) } + let(:record) { FactoryBot.build(:sales_log, mortgageused: 1, 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) @@ -891,6 +1036,22 @@ RSpec.describe Validations::Sales::SaleInformationValidations do expect(record.errors["value"]).to be_empty expect(record.errors["deposit"]).to be_empty expect(record.errors["stairbought"]).to be_empty + expect(record.errors["cashdis"]).to be_empty + expect(record.errors["type"]).to be_empty + end + end + + context "when MORTGAGE + DEPOSIT is within 1£ tolerance of STAIRBOUGHT/100 * VALUE" do + let(:record) { FactoryBot.build(:sales_log, mortgageused: 1, mortgage: 10_000, staircase: 1, deposit: 5_000, value: 30_001, 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 + expect(record.errors["cashdis"]).to be_empty + expect(record.errors["type"]).to be_empty end end end @@ -905,6 +1066,8 @@ RSpec.describe Validations::Sales::SaleInformationValidations do expect(record.errors["value"]).to be_empty expect(record.errors["deposit"]).to be_empty expect(record.errors["stairbought"]).to be_empty + expect(record.errors["cashdis"]).to be_empty + expect(record.errors["type"]).to be_empty end end @@ -924,10 +1087,45 @@ RSpec.describe Validations::Sales::SaleInformationValidations do 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.") + expect(record.errors["mortgageused"]).to include("The deposit is £5,000.00 and the value multiplied by the percentage bought is £8,400.00. These figures should be the same.") + expect(record.errors["value"]).to include("The deposit is £5,000.00 and the value multiplied by the percentage bought is £8,400.00. These figures should be the same.") + expect(record.errors["deposit"]).to include("The deposit is £5,000.00 and the value multiplied by the percentage bought is £8,400.00. These figures should be the same.") + expect(record.errors["stairbought"]).to include("The deposit is £5,000.00 and the value multiplied by the percentage bought is £8,400.00. These figures should be the same.") + expect(record.errors["type"]).to include("The deposit is £5,000.00 and the value multiplied by the percentage bought is £8,400.00. These figures should be the same.") + expect(record.errors["cashdis"]).not_to include("The deposit is £5,000.00 and the value multiplied by the percentage bought is £8,400.00. These figures should be the same.") + end + + context "and it is a social homebuy" do + before do + record.type = 18 + record.cashdis = "200" + end + + it "adds an error" do + sale_information_validator.validate_staircasing_mortgage(record) + expect(record.errors["mortgageused"]).to include("The deposit and cash discount added together is £5,200.00. The value multiplied by the percentage bought is £8,400.00. These figures should be the same.") + expect(record.errors["value"]).to include("The deposit and cash discount added together is £5,200.00. The value multiplied by the percentage bought is £8,400.00. These figures should be the same.") + expect(record.errors["deposit"]).to include("The deposit and cash discount added together is £5,200.00. The value multiplied by the percentage bought is £8,400.00. These figures should be the same.") + expect(record.errors["stairbought"]).to include("The deposit and cash discount added together is £5,200.00. The value multiplied by the percentage bought is £8,400.00. These figures should be the same.") + expect(record.errors["cashdis"]).to include("The deposit and cash discount added together is £5,200.00. The value multiplied by the percentage bought is £8,400.00. These figures should be the same.") + expect(record.errors["type"]).to include("The deposit and cash discount added together is £5,200.00. The value multiplied by the percentage bought is £8,400.00. These figures should be the same.") + end + end + + context "and it is not a shared ownership transaction" do + before do + record.ownershipsch = 2 + end + + it "does not add an error" do + sale_information_validator.validate_non_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 + expect(record.errors["cashdis"]).to be_empty + expect(record.errors["type"]).to be_empty + end end end @@ -942,6 +1140,8 @@ RSpec.describe Validations::Sales::SaleInformationValidations do expect(record.errors["value"]).to be_empty expect(record.errors["deposit"]).to be_empty expect(record.errors["stairbought"]).to be_empty + expect(record.errors["cashdis"]).to be_empty + expect(record.errors["type"]).to be_empty end end end @@ -955,6 +1155,22 @@ RSpec.describe Validations::Sales::SaleInformationValidations do expect(record.errors["value"]).to be_empty expect(record.errors["deposit"]).to be_empty expect(record.errors["stairbought"]).to be_empty + expect(record.errors["cashdis"]).to be_empty + expect(record.errors["type"]).to be_empty + end + end + + context "when DEPOSIT is within 1£ tolerance of STAIRBOUGHT/100 * VALUE" do + let(:record) { FactoryBot.build(:sales_log, mortgageused: 2, staircase: 1, deposit: 15_000, value: 30_001, 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 + expect(record.errors["cashdis"]).to be_empty + expect(record.errors["type"]).to be_empty end end end @@ -969,6 +1185,8 @@ RSpec.describe Validations::Sales::SaleInformationValidations do expect(record.errors["value"]).to be_empty expect(record.errors["deposit"]).to be_empty expect(record.errors["stairbought"]).to be_empty + expect(record.errors["cashdis"]).to be_empty + expect(record.errors["type"]).to be_empty end end end 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 93ab6d9da..e68e95f06 100644 --- a/spec/services/bulk_upload/sales/year2024/row_parser_spec.rb +++ b/spec/services/bulk_upload/sales/year2024/row_parser_spec.rb @@ -1134,6 +1134,32 @@ RSpec.describe BulkUpload::Sales::Year2024::RowParser do expect(parser.errors[:field_109]).to be_empty end end + + context "with non staircasing mortgage error" do + let(:attributes) { setup_section_params.merge(field_9: "30", field_103: "1", field_104: "10000", field_109: "5000", field_101: "30000", field_102: "28", field_86: "2") } + + it "does not add a BU error on type (because it's a setup field and would block log creation)" do + expect(parser.errors[:field_9]).to be_empty + end + + it "includes errors on other related fields" do + expect(parser.errors[:field_104]).to include("The mortgage and deposit added together is £15,000.00. The value multiplied by the percentage bought is £8,400.00. These figures should be the same.") + expect(parser.errors[:field_109]).to include("The mortgage and deposit added together is £15,000.00. The value multiplied by the percentage bought is £8,400.00. These figures should be the same.") + expect(parser.errors[:field_101]).to include("The mortgage and deposit added together is £15,000.00. The value multiplied by the percentage bought is £8,400.00. These figures should be the same.") + expect(parser.errors[:field_102]).to include("The mortgage and deposit added together is £15,000.00. The value multiplied by the percentage bought is £8,400.00. These figures should be the same.") + end + + it "does not add errors to other ownership type fields" do + expect(parser.errors[:field_117]).to be_empty + expect(parser.errors[:field_126]).to be_empty + expect(parser.errors[:field_118]).to be_empty + expect(parser.errors[:field_127]).to be_empty + expect(parser.errors[:field_123]).to be_empty + expect(parser.errors[:field_130]).to be_empty + expect(parser.errors[:field_114]).to be_empty + expect(parser.errors[:field_125]).to be_empty + end + end end describe "#field_117" do