Browse Source

Merge branch 'main' into CLDC-1790-sales-validation-content-updates

# Conflicts:
#	app/models/sales_log.rb
#	app/models/validations/sales/financial_validations.rb
#	db/schema.rb
#	spec/models/validations/sales/financial_validations_spec.rb
CLDC-1790-sales-validation-content-updates
natdeanlewissoftwire 2 years ago
parent
commit
b9d3d2b28b
  1. 21
      app/models/form/sales/pages/old_persons_shared_ownership_value_check.rb
  2. 27
      app/models/form/sales/pages/shared_ownership_deposit_value_check.rb
  3. 23
      app/models/form/sales/questions/old_persons_shared_ownership_value_check.rb
  4. 23
      app/models/form/sales/questions/shared_ownership_deposit_value_check.rb
  5. 2
      app/models/form/sales/subsections/household_characteristics.rb
  6. 2
      app/models/form/sales/subsections/household_needs.rb
  7. 1
      app/models/form/sales/subsections/setup.rb
  8. 5
      app/models/form/sales/subsections/shared_ownership_scheme.rb
  9. 22
      app/models/sales_log.rb
  10. 14
      app/models/validations/sales/financial_validations.rb
  11. 18
      app/models/validations/sales/household_validations.rb
  12. 9
      app/models/validations/sales/sale_information_validations.rb
  13. 10
      app/models/validations/sales/soft_validations.rb
  14. 1
      app/services/bulk_upload/lettings/validator.rb
  15. 8
      config/locales/en.yml
  16. 7
      db/migrate/20230123101256_add_shared_ownership_deposit_value_check.rb
  17. 7
      db/migrate/20230124105247_add_old_persons_shared_ownership_value_check.rb
  18. 5
      db/migrate/20230126145529_add_column_to_bulk_upload_errors.rb
  19. 10
      db/schema.rb
  20. 44
      spec/models/form/sales/pages/old_persons_shared_ownership_value_check_spec.rb
  21. 50
      spec/models/form/sales/pages/shared_ownership_deposit_value_check_spec.rb
  22. 57
      spec/models/form/sales/questions/old_persons_shared_ownership_value_check_spec.rb
  23. 61
      spec/models/form/sales/questions/shared_ownership_deposit_value_check_spec.rb
  24. 2
      spec/models/form/sales/subsections/household_characteristics_spec.rb
  25. 2
      spec/models/form/sales/subsections/household_needs_spec.rb
  26. 1
      spec/models/form/sales/subsections/setup_spec.rb
  27. 3
      spec/models/form/sales/subsections/shared_ownership_scheme_spec.rb
  28. 4
      spec/models/form_handler_spec.rb
  29. 4
      spec/models/form_spec.rb
  30. 10
      spec/models/sales_log_spec.rb
  31. 26
      spec/models/validations/sales/financial_validations_spec.rb
  32. 115
      spec/models/validations/sales/household_validations_spec.rb
  33. 57
      spec/models/validations/sales/sale_information_validations_spec.rb
  34. 104
      spec/models/validations/sales/soft_validations_spec.rb
  35. 74
      spec/models/validations/soft_validations_spec.rb
  36. 9
      spec/services/bulk_upload/lettings/validator_spec.rb

21
app/models/form/sales/pages/old_persons_shared_ownership_value_check.rb

@ -0,0 +1,21 @@
class Form::Sales::Pages::OldPersonsSharedOwnershipValueCheck < ::Form::Page
def initialize(id, hsh, subsection)
super
@depends_on = [
{
"buyers_age_for_old_persons_shared_ownership_invalid?" => true,
},
]
@title_text = {
"translation" => "soft_validations.old_persons_shared_ownership",
"arguments" => [],
}
@informative_text = {}
end
def questions
@questions ||= [
Form::Sales::Questions::OldPersonsSharedOwnershipValueCheck.new(nil, nil, self),
]
end
end

27
app/models/form/sales/pages/shared_ownership_deposit_value_check.rb

@ -0,0 +1,27 @@
class Form::Sales::Pages::SharedOwnershipDepositValueCheck < ::Form::Page
def initialize(id, hsh, subsection)
super
@depends_on = [
{
"shared_ownership_deposit_invalid?" => true,
},
]
@informative_text = {}
@title_text = {
"translation" => "soft_validations.shared_owhership_deposit.title_text",
"arguments" => [
{
"key" => "expected_shared_ownership_deposit_value",
"label" => false,
"i18n_template" => "expected_shared_ownership_deposit_value",
},
],
}
end
def questions
@questions ||= [
Form::Sales::Questions::SharedOwnershipDepositValueCheck.new(nil, nil, self),
]
end
end

23
app/models/form/sales/questions/old_persons_shared_ownership_value_check.rb

@ -0,0 +1,23 @@
class Form::Sales::Questions::OldPersonsSharedOwnershipValueCheck < ::Form::Question
def initialize(id, hsh, page)
super
@id = "old_persons_shared_ownership_value_check"
@check_answer_label = "Shared ownership confirmation"
@header = "Are you sure this is correct?"
@type = "interruption_screen"
@answer_options = {
"0" => { "value" => "Yes" },
"1" => { "value" => "No" },
}
@hidden_in_check_answers = {
"depends_on" => [
{
"old_persons_shared_ownership_value_check" => 0,
},
{
"old_persons_shared_ownership_value_check" => 1,
},
],
}
end
end

23
app/models/form/sales/questions/shared_ownership_deposit_value_check.rb

@ -0,0 +1,23 @@
class Form::Sales::Questions::SharedOwnershipDepositValueCheck < ::Form::Question
def initialize(id, hsh, page)
super
@id = "shared_ownership_deposit_value_check"
@check_answer_label = "Shared ownership deposit confirmation"
@type = "interruption_screen"
@header = "Are you sure this is correct?"
@answer_options = {
"0" => { "value" => "Yes" },
"1" => { "value" => "No" },
}
@hidden_in_check_answers = {
"depends_on" => [
{
"shared_ownership_deposit_value_check" => 0,
},
{
"shared_ownership_deposit_value_check" => 1,
},
],
}
end
end

2
app/models/form/sales/subsections/household_characteristics.rb

@ -13,6 +13,7 @@ class Form::Sales::Subsections::HouseholdCharacteristics < ::Form::Subsection
Form::Sales::Pages::Age1.new(nil, nil, self),
Form::Sales::Pages::RetirementValueCheck.new("age_1_retirement_value_check", nil, self, person_index: 1),
Form::Sales::Pages::RetirementValueCheck.new("age_1_retirement_value_check_joint_purchase", nil, self, person_index: 1),
Form::Sales::Pages::OldPersonsSharedOwnershipValueCheck.new("age_1_old_persons_shared_ownership_value_check", nil, self),
Form::Sales::Pages::GenderIdentity1.new(nil, nil, self),
Form::Sales::Pages::RetirementValueCheck.new("gender_1_retirement_value_check", nil, self, person_index: 1),
Form::Sales::Pages::RetirementValueCheck.new("gender_1_retirement_value_check_joint_purchase", nil, self, person_index: 1),
@ -31,6 +32,7 @@ class Form::Sales::Subsections::HouseholdCharacteristics < ::Form::Subsection
Form::Sales::Pages::Buyer2RelationshipToBuyer1.new(nil, nil, self),
Form::Sales::Pages::Age2.new(nil, nil, self),
Form::Sales::Pages::RetirementValueCheck.new("age_2_retirement_value_check_joint_purchase", nil, self, person_index: 2),
Form::Sales::Pages::OldPersonsSharedOwnershipValueCheck.new("age_2_old_persons_shared_ownership_value_check", nil, self),
Form::Sales::Pages::GenderIdentity2.new(nil, nil, self),
Form::Sales::Pages::RetirementValueCheck.new("gender_2_retirement_value_check_joint_purchase", nil, self, person_index: 2),
Form::Sales::Pages::Buyer2WorkingSituation.new(nil, nil, self),

2
app/models/form/sales/subsections/household_needs.rb

@ -2,7 +2,7 @@ class Form::Sales::Subsections::HouseholdNeeds < ::Form::Subsection
def initialize(id, hsh, section)
super
@id = "household_needs"
@label = "Household needs"
@label = "Other household information"
@depends_on = [{ "setup_completed?" => true }]
end

1
app/models/form/sales/subsections/setup.rb

@ -15,6 +15,7 @@ class Form::Sales::Subsections::Setup < ::Form::Subsection
Form::Sales::Pages::SharedOwnershipType.new(nil, nil, self),
Form::Sales::Pages::DiscountedOwnershipType.new(nil, nil, self),
Form::Sales::Pages::OutrightOwnershipType.new(nil, nil, self),
Form::Sales::Pages::OldPersonsSharedOwnershipValueCheck.new("ownership_type_old_persons_shared_ownership_value_check", nil, self),
Form::Sales::Pages::BuyerCompany.new(nil, nil, self),
Form::Sales::Pages::BuyerLive.new(nil, nil, self),
Form::Sales::Pages::JointPurchase.new(nil, nil, self),

5
app/models/form/sales/subsections/shared_ownership_scheme.rb

@ -21,15 +21,18 @@ class Form::Sales::Subsections::SharedOwnershipScheme < ::Form::Subsection
Form::Sales::Pages::PreviousPropertyType.new(nil, nil, self),
Form::Sales::Pages::PreviousTenure.new(nil, nil, self),
Form::Sales::Pages::AboutPriceSharedOwnership.new(nil, nil, self),
Form::Sales::Pages::SharedOwnershipDepositValueCheck.new("shared_ownership_equity_value_check", nil, self),
Form::Sales::Pages::Mortgageused.new("mortgage_used_shared_ownership", nil, self),
Form::Sales::Pages::MortgageAmount.new("mortgage_amount_shared_ownership", nil, self),
Form::Sales::Pages::SharedOwnershipDepositValueCheck.new("shared_ownership_mortgage_amount_value_check", nil, self),
Form::Sales::Pages::MortgageLender.new("mortgage_lender_shared_ownership", nil, self),
Form::Sales::Pages::MortgageLenderOther.new("mortgage_lender_other_shared_ownership", nil, self),
Form::Sales::Pages::MortgageLength.new("mortgage_length_shared_ownership", nil, self),
Form::Sales::Pages::ExtraBorrowing.new("extra_borrowing_shared_ownership", nil, self),
Form::Sales::Pages::AboutDepositWithDiscount.new(nil, nil, self),
Form::Sales::Pages::AboutDepositWithoutDiscount.new("about_deposit_shared_ownership", nil, self),
Form::Sales::Pages::DepositValueCheck.new("shared_ownership_deposit_value_check", nil, self),
Form::Sales::Pages::DepositValueCheck.new("deposit_value_check", nil, self),
Form::Sales::Pages::SharedOwnershipDepositValueCheck.new("shared_ownership_deposit_value_check", nil, self),
Form::Sales::Pages::MonthlyRent.new(nil, nil, self),
Form::Sales::Pages::LeaseholdCharges.new("leasehold_charges_shared_ownership", nil, self),
]

22
app/models/sales_log.rb

@ -34,7 +34,7 @@ class SalesLog < Log
scope :search_by, ->(param) { filter_by_id(param) }
scope :filter_by_organisation, ->(org, _user = nil) { where(owning_organisation: org) }
OPTIONAL_FIELDS = %w[purchid].freeze
OPTIONAL_FIELDS = %w[purchid old_persons_shared_ownership_value_check].freeze
RETIREMENT_AGES = { "M" => 65, "F" => 60, "X" => 65 }.freeze
def startdate
@ -159,6 +159,12 @@ class SalesLog < Log
end
end
def expected_shared_ownership_deposit_value
return unless value && equity
(value * equity / 100).round(2)
end
def process_postcode(postcode, postcode_known_key, la_inferred_key, la_key)
return if postcode.blank?
@ -212,6 +218,20 @@ class SalesLog < Log
type == 24
end
def shared_owhership_scheme?
ownershipsch == 1
end
def buyers_age_for_old_persons_shared_ownership_invalid?
return unless old_persons_shared_ownership?
(joint_purchase? && ages_unknown_or_under_64?([1, 2])) || (not_joint_purchase? && ages_unknown_or_under_64?([1]))
end
def ages_unknown_or_under_64?(person_indexes)
person_indexes.all? { |person_num| self["age#{person_num}"].present? && self["age#{person_num}"] < 64 || self["age#{person_num}_known"] == 1 }
end
def allowed_income_soft_min
ALLOWED_INCOME_RANGES[ecstat1].soft_min
end

14
app/models/validations/sales/financial_validations.rb

@ -3,11 +3,19 @@ module Validations::Sales::FinancialValidations
# or 'validate_' to run on submit as well
def validate_income1(record)
if record.ecstat1 && record.income1 && record.ownershipsch == 1
if record.london_property?
record.errors.add :income1, I18n.t("validations.financial.income1.over_hard_max.inside_london") if record.income1 > 90_000
if record.ecstat1 && record.income1 && record.la && record.ownershipsch == 1
if record.london_property? && record.income1 > 90_000
record.errors.add :income1, I18n.t("validations.financial.income1.over_hard_max.inside_london")
record.errors.add :ecstat1, I18n.t("validations.financial.income1.over_hard_max.inside_london")
record.errors.add :ownershipsch, I18n.t("validations.financial.income1.over_hard_max.inside_london")
record.errors.add :la, I18n.t("validations.financial.income1.over_hard_max.inside_london")
record.errors.add :postcode_full, I18n.t("validations.financial.income1.over_hard_max.inside_london")
elsif record.income1 > 80_000
record.errors.add :income1, I18n.t("validations.financial.income1.over_hard_max.outside_london")
record.errors.add :ecstat1, I18n.t("validations.financial.income1.over_hard_max.outside_london")
record.errors.add :ownershipsch, I18n.t("validations.financial.income1.over_hard_max.outside_london")
record.errors.add :la, I18n.t("validations.financial.income1.over_hard_max.outside_london")
record.errors.add :postcode_full, I18n.t("validations.financial.income1.over_hard_max.outside_london")
end
end
end

18
app/models/validations/sales/household_validations.rb

@ -18,20 +18,6 @@ module Validations::Sales::HouseholdValidations
shared_validate_partner_count(record, 6)
end
def validate_buyers_age_for_old_persons_shared_ownership(record)
if record.old_persons_shared_ownership?
if record.joint_purchase? && ages_unknown_or_under_64?(record, [1, 2])
record.errors.add :age1, I18n.t("validations.household.old_persons_shared_ownership")
record.errors.add :age2, I18n.t("validations.household.old_persons_shared_ownership")
record.errors.add :type, I18n.t("validations.household.old_persons_shared_ownership")
end
if record.not_joint_purchase? && ages_unknown_or_under_64?(record, [1])
record.errors.add :age1, I18n.t("validations.household.old_persons_shared_ownership")
record.errors.add :type, I18n.t("validations.household.old_persons_shared_ownership")
end
end
end
def validate_previous_postcode(record)
return unless record.postcode_full && record.ppostcode_full && record.discounted_ownership_sale?
@ -116,8 +102,4 @@ private
def tenant_is_economic_child?(economic_status)
economic_status == 9
end
def ages_unknown_or_under_64?(record, person_indexes)
person_indexes.all? { |person_num| record["age#{person_num}"].present? && record["age#{person_num}"] < 64 || record["age#{person_num}_known"] == 1 }
end
end

9
app/models/validations/sales/sale_information_validations.rb

@ -54,4 +54,13 @@ module Validations::Sales::SaleInformationValidations
end
end
end
def validate_basic_monthly_rent(record)
return unless record.mrent && record.ownershipsch && record.type
if record.shared_owhership_scheme? && !record.old_persons_shared_ownership? && record.mrent > 9999
record.errors.add :mrent, I18n.t("validations.sale_information.monthly_rent.higher_than_expected")
record.errors.add :type, I18n.t("validations.sale_information.monthly_rent.higher_than_expected")
end
end
end

10
app/models/validations/sales/soft_validations.rb

@ -43,6 +43,16 @@ module Validations::Sales::SoftValidations
extrabor != 1 && mortgage + deposit > value - value * discount / 100
end
def shared_ownership_deposit_invalid?
return unless mortgage || mortgageused == 2
return unless cashdis || !is_type_discount?
return unless deposit && value && equity
cash_discount = cashdis || 0
mortgage_value = mortgage || 0
mortgage_value + deposit + cash_discount != value * equity / 100
end
def hodate_3_years_or_more_saledate?
return unless hodate && saledate

1
app/services/bulk_upload/lettings/validator.rb

@ -164,6 +164,7 @@ class BulkUpload::Lettings::Validator
property_ref: row_parser.field_100,
row:,
cell: "#{cols[field_number_for_attribute(error.attribute) - col_offset + 1]}#{row}",
col: cols[field_number_for_attribute(error.attribute) - col_offset + 1],
)
end
end

8
config/locales/en.yml

@ -370,10 +370,9 @@ en:
not_internal_transfer: "Answer cannot be ‘permanently decanted from another property owned by this landlord’ as you told us the source of referral for this tenancy was not an internal transfer"
condition_effects:
no_choices: "You cannot answer this question as you told us nobody in the household has a physical or mental health condition (or other illness) expected to last 12 months or more"
old_persons_shared_ownership: "Are you sure? At least one buyer should be aged over 64 for Older persons‘ shared ownership scheme"
postcode:
discounted_ownership: "Last settled accommodation and discounted ownership property postcodes must match"
tenancy:
length:
fixed_term_not_required: "You must only answer the length of the tenancy if it's fixed-term"
@ -426,6 +425,8 @@ en:
previous_property_beds:
property_type_bedsit: "A bedsit cannot have more than 1 bedroom"
discounted_ownership_value: "Mortgage, deposit, and grant total must equal £%{value_with_discount}"
monthly_rent:
higher_than_expected: "Basic monthly rent must be between £0 and £9,999"
soft_validations:
net_income:
@ -460,6 +461,9 @@ en:
title_text: "You told us the time between the start of the tenancy and the major repairs completion date is more than 2 years"
void_date:
title_text: "You told us the time between the start of the tenancy and the void date is more than 2 years"
shared_owhership_deposit:
title_text: "Mortgage, deposit and cash discount total should equal £%{expected_shared_ownership_deposit_value}"
old_persons_shared_ownership: "At least one buyer should be aged over 64 for Older persons’ shared ownership scheme"
devise:
two_factor_authentication:

7
db/migrate/20230123101256_add_shared_ownership_deposit_value_check.rb

@ -0,0 +1,7 @@
class AddSharedOwnershipDepositValueCheck < ActiveRecord::Migration[7.0]
def change
change_table :sales_logs, bulk: true do |t|
t.column :shared_ownership_deposit_value_check, :integer
end
end
end

7
db/migrate/20230124105247_add_old_persons_shared_ownership_value_check.rb

@ -0,0 +1,7 @@
class AddOldPersonsSharedOwnershipValueCheck < ActiveRecord::Migration[7.0]
def change
change_table :sales_logs, bulk: true do |t|
t.column :old_persons_shared_ownership_value_check, :integer
end
end
end

5
db/migrate/20230126145529_add_column_to_bulk_upload_errors.rb

@ -0,0 +1,5 @@
class AddColumnToBulkUploadErrors < ActiveRecord::Migration[7.0]
def change
add_column :bulk_upload_errors, :col, :text
end
end

10
db/schema.rb

@ -10,7 +10,7 @@
#
# It's strongly recommended that you check this file into your version control system.
ActiveRecord::Schema[7.0].define(version: 2023_01_23_160741) do
ActiveRecord::Schema[7.0].define(version: 2023_01_26_145529) do
# These are extensions that must be enabled in order to support this database
enable_extension "plpgsql"
@ -25,6 +25,7 @@ ActiveRecord::Schema[7.0].define(version: 2023_01_23_160741) do
t.text "error"
t.datetime "created_at", null: false
t.datetime "updated_at", null: false
t.text "col"
t.index ["bulk_upload_id"], name: "index_bulk_upload_errors_on_bulk_upload_id"
end
@ -486,9 +487,9 @@ ActiveRecord::Schema[7.0].define(version: 2023_01_23_160741) do
t.integer "hoyear"
t.integer "fromprop"
t.integer "socprevten"
t.integer "mortlen"
t.integer "mortgagelender"
t.string "mortgagelenderother"
t.integer "mortlen"
t.integer "extrabor"
t.integer "hhmemb"
t.integer "totadult"
@ -501,10 +502,13 @@ ActiveRecord::Schema[7.0].define(version: 2023_01_23_160741) do
t.boolean "is_la_inferred"
t.bigint "bulk_upload_id"
t.integer "retirement_value_check"
t.integer "deposit_and_mortgage_value_check"
t.integer "grant_value_check"
t.integer "hodate_check"
t.integer "extrabor_value_check"
t.integer "grant_value_check"
t.integer "old_persons_shared_ownership_value_check"
t.index ["bulk_upload_id"], name: "index_sales_logs_on_bulk_upload_id"
t.integer "shared_ownership_deposit_value_check"
t.index ["created_by_id"], name: "index_sales_logs_on_created_by_id"
t.index ["owning_organisation_id"], name: "index_sales_logs_on_owning_organisation_id"
t.index ["updated_by_id"], name: "index_sales_logs_on_updated_by_id"

44
spec/models/form/sales/pages/old_persons_shared_ownership_value_check_spec.rb

@ -0,0 +1,44 @@
require "rails_helper"
RSpec.describe Form::Sales::Pages::OldPersonsSharedOwnershipValueCheck, type: :model do
subject(:page) { described_class.new(page_id, page_definition, subsection) }
let(:page_id) { "old_persons_shared_ownership_value_check" }
let(:page_definition) { nil }
let(:subsection) { instance_double(Form::Subsection) }
it "has correct subsection" do
expect(page.subsection).to eq(subsection)
end
it "has correct questions" do
expect(page.questions.map(&:id)).to eq(%w[old_persons_shared_ownership_value_check])
end
it "has the correct id" do
expect(page.id).to eq("old_persons_shared_ownership_value_check")
end
it "has the correct header" do
expect(page.header).to be_nil
end
it "has correct depends_on" do
expect(page.depends_on).to eq([
{
"buyers_age_for_old_persons_shared_ownership_invalid?" => true,
},
])
end
it "has the correct title_text" do
expect(page.title_text).to eq({
"translation" => "soft_validations.old_persons_shared_ownership",
"arguments" => [],
})
end
it "has the correct informative_text" do
expect(page.informative_text).to eq({})
end
end

50
spec/models/form/sales/pages/shared_ownership_deposit_value_check_spec.rb

@ -0,0 +1,50 @@
require "rails_helper"
RSpec.describe Form::Sales::Pages::SharedOwnershipDepositValueCheck, type: :model do
subject(:page) { described_class.new(page_id, page_definition, subsection) }
let(:page_id) { "shared_ownership_deposit_value_check" }
let(:page_definition) { nil }
let(:subsection) { instance_double(Form::Subsection) }
it "has correct subsection" do
expect(page.subsection).to eq(subsection)
end
it "has correct questions" do
expect(page.questions.map(&:id)).to eq(%w[shared_ownership_deposit_value_check])
end
it "has the correct id" do
expect(page.id).to eq("shared_ownership_deposit_value_check")
end
it "has the correct header" do
expect(page.header).to be_nil
end
it "has correct depends_on" do
expect(page.depends_on).to eq([
{
"shared_ownership_deposit_invalid?" => true,
},
])
end
it "has the correct title_text" do
expect(page.title_text).to eq({
"translation" => "soft_validations.shared_owhership_deposit.title_text",
"arguments" => [
{
"key" => "expected_shared_ownership_deposit_value",
"label" => false,
"i18n_template" => "expected_shared_ownership_deposit_value",
},
],
})
end
it "has the correct informative_text" do
expect(page.informative_text).to eq({})
end
end

57
spec/models/form/sales/questions/old_persons_shared_ownership_value_check_spec.rb

@ -0,0 +1,57 @@
require "rails_helper"
RSpec.describe Form::Sales::Questions::OldPersonsSharedOwnershipValueCheck, type: :model do
subject(:question) { described_class.new(question_id, question_definition, page) }
let(:question_id) { nil }
let(:question_definition) { nil }
let(:page) { instance_double(Form::Page) }
it "has correct page" do
expect(question.page).to eq(page)
end
it "has the correct id" do
expect(question.id).to eq("old_persons_shared_ownership_value_check")
end
it "has the correct header" do
expect(question.header).to eq("Are you sure this is correct?")
end
it "has the correct check_answer_label" do
expect(question.check_answer_label).to eq("Shared ownership confirmation")
end
it "has the correct type" do
expect(question.type).to eq("interruption_screen")
end
it "is not marked as derived" do
expect(question.derived?).to be false
end
it "has the correct hint" do
expect(question.hint_text).to be_nil
end
it "has the correct answer_options" do
expect(question.answer_options).to eq({
"0" => { "value" => "Yes" },
"1" => { "value" => "No" },
})
end
it "has the correct hidden_in_check_answers" do
expect(question.hidden_in_check_answers).to eq({
"depends_on" => [
{
"old_persons_shared_ownership_value_check" => 0,
},
{
"old_persons_shared_ownership_value_check" => 1,
},
],
})
end
end

61
spec/models/form/sales/questions/shared_ownership_deposit_value_check_spec.rb

@ -0,0 +1,61 @@
require "rails_helper"
RSpec.describe Form::Sales::Questions::SharedOwnershipDepositValueCheck, type: :model do
subject(:question) { described_class.new(question_id, question_definition, page) }
let(:question_id) { nil }
let(:question_definition) { nil }
let(:page) { instance_double(Form::Page) }
it "has correct page" do
expect(question.page).to eq(page)
end
it "has the correct id" do
expect(question.id).to eq("shared_ownership_deposit_value_check")
end
it "has the correct header" do
expect(question.header).to eq("Are you sure this is correct?")
end
it "has the correct check_answer_label" do
expect(question.check_answer_label).to eq("Shared ownership deposit confirmation")
end
it "has the correct type" do
expect(question.type).to eq("interruption_screen")
end
it "is not marked as derived" do
expect(question.derived?).to be false
end
it "has the correct hint" do
expect(question.hint_text).to be_nil
end
# it "has a correct check_answers_card_number" do
# expect(question.check_answers_card_number).to eq(0)
# end
it "has the correct answer_options" do
expect(question.answer_options).to eq({
"0" => { "value" => "Yes" },
"1" => { "value" => "No" },
})
end
it "has the correct hidden_in_check_answers" do
expect(question.hidden_in_check_answers).to eq({
"depends_on" => [
{
"shared_ownership_deposit_value_check" => 0,
},
{
"shared_ownership_deposit_value_check" => 1,
},
],
})
end
end

2
spec/models/form/sales/subsections/household_characteristics_spec.rb

@ -19,6 +19,7 @@ RSpec.describe Form::Sales::Subsections::HouseholdCharacteristics, type: :model
buyer_1_age
age_1_retirement_value_check
age_1_retirement_value_check_joint_purchase
age_1_old_persons_shared_ownership_value_check
buyer_1_gender_identity
gender_1_retirement_value_check
gender_1_retirement_value_check_joint_purchase
@ -37,6 +38,7 @@ RSpec.describe Form::Sales::Subsections::HouseholdCharacteristics, type: :model
buyer_2_relationship_to_buyer_1
buyer_2_age
age_2_retirement_value_check_joint_purchase
age_2_old_persons_shared_ownership_value_check
buyer_2_gender_identity
gender_2_retirement_value_check_joint_purchase
buyer_2_working_situation

2
spec/models/form/sales/subsections/household_needs_spec.rb

@ -30,7 +30,7 @@ RSpec.describe Form::Sales::Subsections::HouseholdNeeds, type: :model do
end
it "has the correct label" do
expect(household_characteristics.label).to eq("Household needs")
expect(household_characteristics.label).to eq("Other household information")
end
it "has correct depends on" do

1
spec/models/form/sales/subsections/setup_spec.rb

@ -22,6 +22,7 @@ RSpec.describe Form::Sales::Subsections::Setup, type: :model do
shared_ownership_type
discounted_ownership_type
outright_ownership_type
ownership_type_old_persons_shared_ownership_value_check
buyer_company
buyer_live
joint_purchase

3
spec/models/form/sales/subsections/shared_ownership_scheme_spec.rb

@ -27,14 +27,17 @@ RSpec.describe Form::Sales::Subsections::SharedOwnershipScheme, type: :model do
previous_property_type
shared_ownership_previous_tenure
about_price_shared_ownership
shared_ownership_equity_value_check
mortgage_used_shared_ownership
mortgage_amount_shared_ownership
shared_ownership_mortgage_amount_value_check
mortgage_lender_shared_ownership
mortgage_lender_other_shared_ownership
mortgage_length_shared_ownership
extra_borrowing_shared_ownership
about_deposit_with_discount
about_deposit_shared_ownership
deposit_value_check
shared_ownership_deposit_value_check
monthly_rent
leasehold_charges_shared_ownership

4
spec/models/form_handler_spec.rb

@ -52,14 +52,14 @@ RSpec.describe FormHandler do
it "is able to load a current sales form" do
form = form_handler.get_form("current_sales")
expect(form).to be_a(Form)
expect(form.pages.count).to eq(188)
expect(form.pages.count).to eq(194)
expect(form.name).to eq("2022_2023_sales")
end
it "is able to load a previous sales form" do
form = form_handler.get_form("previous_sales")
expect(form).to be_a(Form)
expect(form.pages.count).to eq(188)
expect(form.pages.count).to eq(194)
expect(form.name).to eq("2021_2022_sales")
end
end

4
spec/models/form_spec.rb

@ -218,9 +218,9 @@ RSpec.describe Form, type: :model do
expect(form.sections[0].class).to eq(Form::Sales::Sections::Setup)
expect(form.subsections.count).to eq(1)
expect(form.subsections.first.id).to eq("setup")
expect(form.pages.count).to eq(12)
expect(form.pages.count).to eq(13)
expect(form.pages.first.id).to eq("organisation")
expect(form.questions.count).to eq(13)
expect(form.questions.count).to eq(14)
expect(form.questions.first.id).to eq("owning_organisation_id")
expect(form.start_date).to eq(Time.zone.parse("2022-04-01"))
expect(form.end_date).to eq(Time.zone.parse("2023-07-01"))

10
spec/models/sales_log_spec.rb

@ -47,7 +47,7 @@ RSpec.describe SalesLog, type: :model do
let(:sales_log) { build(:sales_log) }
it "returns optional fields" do
expect(sales_log.optional_fields).to eq(%w[purchid])
expect(sales_log.optional_fields).to eq(%w[purchid old_persons_shared_ownership_value_check])
end
end
@ -339,4 +339,12 @@ RSpec.describe SalesLog, type: :model do
expect(record_from_db["prevloc"]).to eq(nil)
end
end
describe "expected_shared_ownership_deposit_value" do
let!(:completed_sales_log) { create(:sales_log, :completed, ownershipsch: 1, type: 2, value: 1000, equity: 50) }
it "is set to completed for a completed sales log" do
expect(completed_sales_log.expected_shared_ownership_deposit_value).to eq(500)
end
end
end

26
spec/models/validations/sales/financial_validations_spec.rb

@ -6,7 +6,7 @@ RSpec.describe Validations::Sales::FinancialValidations do
let(:validator_class) { Class.new { include Validations::Sales::FinancialValidations } }
describe "income validations" do
let(:record) { FactoryBot.create(:sales_log, ownershipsch: 1) }
let(:record) { FactoryBot.create(:sales_log, ownershipsch: 1, la: "E08000035") }
context "with shared ownership" do
context "and non london borough" do
@ -17,6 +17,14 @@ RSpec.describe Validations::Sales::FinancialValidations do
financial_validator.validate_income1(record)
expect(record.errors["income1"])
.to include(match I18n.t("validations.financial.income1.over_hard_max.outside_london"))
expect(record.errors["ecstat1"])
.to include(match I18n.t("validations.financial.income1.over_hard_max.outside_london"))
expect(record.errors["ownershipsch"])
.to include(match I18n.t("validations.financial.income1.over_hard_max.outside_london"))
expect(record.errors["la"])
.to include(match I18n.t("validations.financial.income1.over_hard_max.outside_london"))
expect(record.errors["postcode_full"])
.to include(match I18n.t("validations.financial.income1.over_hard_max.outside_london"))
end
end
@ -25,6 +33,10 @@ RSpec.describe Validations::Sales::FinancialValidations do
record.ecstat1 = 1
financial_validator.validate_income1(record)
expect(record.errors["income1"]).to be_empty
expect(record.errors["ecstat1"]).to be_empty
expect(record.errors["ownershipsch"]).to be_empty
expect(record.errors["la"]).to be_empty
expect(record.errors["postcode_full"]).to be_empty
end
end
@ -41,6 +53,14 @@ RSpec.describe Validations::Sales::FinancialValidations do
financial_validator.validate_income1(record)
expect(record.errors["income1"])
.to include(match I18n.t("validations.financial.income1.over_hard_max.inside_london"))
expect(record.errors["ecstat1"])
.to include(match I18n.t("validations.financial.income1.over_hard_max.inside_london"))
expect(record.errors["ownershipsch"])
.to include(match I18n.t("validations.financial.income1.over_hard_max.inside_london"))
expect(record.errors["la"])
.to include(match I18n.t("validations.financial.income1.over_hard_max.inside_london"))
expect(record.errors["postcode_full"])
.to include(match I18n.t("validations.financial.income1.over_hard_max.inside_london"))
end
end
@ -49,6 +69,10 @@ RSpec.describe Validations::Sales::FinancialValidations do
record.ecstat1 = 1
financial_validator.validate_income1(record)
expect(record.errors["income1"]).to be_empty
expect(record.errors["ecstat1"]).to be_empty
expect(record.errors["ownershipsch"]).to be_empty
expect(record.errors["la"]).to be_empty
expect(record.errors["postcode_full"]).to be_empty
end
end
end

115
spec/models/validations/sales/household_validations_spec.rb

@ -164,121 +164,6 @@ RSpec.describe Validations::Sales::HouseholdValidations do
expect(record.errors["ecstat2"])
.to include(match I18n.t("validations.household.ecstat.student_16_19.cannot_be_student.child_not_16_19"))
end
context "when it is a joint purchase and both buyers are over 64" do
let(:record) { FactoryBot.build(:sales_log, jointpur: 1, age1: 65, age2: 66, type: 24) }
it "does not add an error" do
household_validator.validate_buyers_age_for_old_persons_shared_ownership(record)
expect(record.errors).not_to be_present
end
end
context "when it is a joint purchase and first buyer is over 64" do
let(:record) { FactoryBot.build(:sales_log, jointpur: 1, age1: 65, age2: 40, type: 24) }
it "does not add an error" do
household_validator.validate_buyers_age_for_old_persons_shared_ownership(record)
expect(record.errors).not_to be_present
end
end
context "when it is a joint purchase and second buyer is over 64" do
let(:record) { FactoryBot.build(:sales_log, jointpur: 1, age1: 43, age2: 64, type: 24) }
it "does not add an error" do
household_validator.validate_buyers_age_for_old_persons_shared_ownership(record)
expect(record.errors).not_to be_present
end
end
context "when it is a joint purchase and neither of the buyers are over 64" do
let(:record) { FactoryBot.build(:sales_log, jointpur: 1, age1: 43, age2: 33, type: 24) }
it "adds an error" do
household_validator.validate_buyers_age_for_old_persons_shared_ownership(record)
expect(record.errors["age1"])
.to include(match I18n.t("validations.household.old_persons_shared_ownership"))
expect(record.errors["age2"])
.to include(match I18n.t("validations.household.old_persons_shared_ownership"))
expect(record.errors["type"])
.to include(match I18n.t("validations.household.old_persons_shared_ownership"))
end
end
context "when it is a joint purchase and first buyer is under 64 and the second buyers' age is unknown" do
let(:record) { FactoryBot.build(:sales_log, jointpur: 1, age1: 43, age2_known: 1, type: 24) }
it "adds an error" do
household_validator.validate_buyers_age_for_old_persons_shared_ownership(record)
expect(record.errors["age1"])
.to include(match I18n.t("validations.household.old_persons_shared_ownership"))
expect(record.errors["age2"])
.to include(match I18n.t("validations.household.old_persons_shared_ownership"))
expect(record.errors["type"])
.to include(match I18n.t("validations.household.old_persons_shared_ownership"))
end
end
context "when it is a joint purchase and neither of the buyers ages are known" do
let(:record) { FactoryBot.build(:sales_log, jointpur: 1, age1_known: 1, age2_known: 1, type: 24) }
it "adds an error" do
household_validator.validate_buyers_age_for_old_persons_shared_ownership(record)
expect(record.errors["age1"])
.to include(match I18n.t("validations.household.old_persons_shared_ownership"))
expect(record.errors["age2"])
.to include(match I18n.t("validations.household.old_persons_shared_ownership"))
expect(record.errors["type"])
.to include(match I18n.t("validations.household.old_persons_shared_ownership"))
end
end
context "when it is not a joint purchase and the buyer is over 64" do
let(:record) { FactoryBot.build(:sales_log, jointpur: 2, age1: 70, type: 24) }
it "does not add an error" do
household_validator.validate_buyers_age_for_old_persons_shared_ownership(record)
expect(record.errors).not_to be_present
end
end
context "when it is not a joint purchase and the buyer is under 64" do
let(:record) { FactoryBot.build(:sales_log, jointpur: 2, age1: 20, type: 24) }
it "adds an error" do
household_validator.validate_buyers_age_for_old_persons_shared_ownership(record)
expect(record.errors["age1"])
.to include(match I18n.t("validations.household.old_persons_shared_ownership"))
expect(record.errors["age2"])
.to be_empty
expect(record.errors["type"])
.to include(match I18n.t("validations.household.old_persons_shared_ownership"))
end
end
context "when it is not a joint purchase and the buyers age is not known" do
let(:record) { FactoryBot.build(:sales_log, jointpur: 2, age1_known: 1, type: 24) }
it "adds an error" do
household_validator.validate_buyers_age_for_old_persons_shared_ownership(record)
expect(record.errors["age1"])
.to include(match I18n.t("validations.household.old_persons_shared_ownership"))
expect(record.errors["age2"])
.to be_empty
expect(record.errors["type"])
.to include(match I18n.t("validations.household.old_persons_shared_ownership"))
end
end
end
describe "previous postcode validations" do

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

@ -371,4 +371,61 @@ RSpec.describe Validations::Sales::SaleInformationValidations do
end
end
end
describe "#validate_basic_monthly_rent" do
context "when within permitted bounds" do
let(:record) { build(:sales_log, mrent: 9998, ownershipsch: 1, type: 2) }
it "does not add an error" do
sale_information_validator.validate_basic_monthly_rent(record)
expect(record.errors[:mrent]).not_to be_present
expect(record.errors[:type]).not_to be_present
end
end
context "when the rent is blank" do
let(:record) { build(:sales_log, mrent: nil, ownershipsch: 1, type: 2) }
it "does not add an error" do
sale_information_validator.validate_basic_monthly_rent(record)
expect(record.errors[:mrent]).not_to be_present
expect(record.errors[:type]).not_to be_present
end
end
context "when the type is old persons shared ownership" do
let(:record) { build(:sales_log, mrent: 100_000, ownershipsch: 1, type: 24) }
it "does not add an error" do
sale_information_validator.validate_basic_monthly_rent(record)
expect(record.errors[:mrent]).not_to be_present
expect(record.errors[:type]).not_to be_present
end
end
context "when the type is blank" do
let(:record) { build(:sales_log, mrent: 100_000, ownershipsch: 1, type: nil) }
it "does not add an error" do
sale_information_validator.validate_basic_monthly_rent(record)
expect(record.errors[:mrent]).not_to be_present
expect(record.errors[:type]).not_to be_present
end
end
context "when higher than upper bound" do
let(:record) { build(:sales_log, mrent: 100_000, ownershipsch: 1, type: 2) }
it "adds an error" do
sale_information_validator.validate_basic_monthly_rent(record)
expect(record.errors[:mrent]).to include(I18n.t("validations.sale_information.monthly_rent.higher_than_expected"))
expect(record.errors[:type]).to include(I18n.t("validations.sale_information.monthly_rent.higher_than_expected"))
end
end
end
end

104
spec/models/validations/sales/soft_validations_spec.rb

@ -321,6 +321,110 @@ RSpec.describe Validations::Sales::SoftValidations do
.not_to be_deposit_over_soft_max
end
end
context "when validating shared ownership deposit" do
it "returns false 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
expect(record)
.not_to be_shared_ownership_deposit_invalid
end
it "returns false 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
expect(record)
.not_to be_shared_ownership_deposit_invalid
end
it "returns true 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
expect(record)
.to be_shared_ownership_deposit_invalid
end
it "returns false if no deposit is given" do
record.mortgage = 1000
record.deposit = nil
record.cashdis = 1000
record.value = 3000
record.equity = 100
expect(record)
.not_to be_shared_ownership_deposit_invalid
end
it "returns false 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
expect(record)
.not_to be_shared_ownership_deposit_invalid
end
it "returns true if no cashdis is given and cashdis is not routed to" do
record.mortgage = 1000
record.deposit = 1000
record.type = 2
record.cashdis = nil
record.value = 3000
record.equity = 100
expect(record)
.to be_shared_ownership_deposit_invalid
end
it "returns false if no value is given" do
record.mortgage = 1000
record.deposit = 1000
record.cashdis = 1000
record.value = nil
record.equity = 100
expect(record)
.not_to be_shared_ownership_deposit_invalid
end
it "returns false if no equity is given" do
record.mortgage = 1000
record.deposit = 1000
record.cashdis = 1000
record.value = 3000
record.equity = nil
expect(record)
.not_to be_shared_ownership_deposit_invalid
end
it "returns true 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
expect(record)
.to be_shared_ownership_deposit_invalid
end
end
end
describe "hodate_more_than_3_years_before_saledate" do

74
spec/models/validations/soft_validations_spec.rb

@ -237,4 +237,78 @@ RSpec.describe Validations::SoftValidations do
end
end
end
describe "old persons shared ownership soft validations" do
context "when it is a joint purchase and both buyers are over 64" do
let(:record) { FactoryBot.build(:sales_log, jointpur: 1, age1: 65, age2: 66, type: 24) }
it "returns false" do
expect(record.buyers_age_for_old_persons_shared_ownership_invalid?).to be false
end
end
context "when it is a joint purchase and first buyer is over 64" do
let(:record) { FactoryBot.build(:sales_log, jointpur: 1, age1: 65, age2: 40, type: 24) }
it "returns false" do
expect(record.buyers_age_for_old_persons_shared_ownership_invalid?).to be false
end
end
context "when it is a joint purchase and second buyer is over 64" do
let(:record) { FactoryBot.build(:sales_log, jointpur: 1, age1: 43, age2: 64, type: 24) }
it "returns false" do
expect(record.buyers_age_for_old_persons_shared_ownership_invalid?).to be false
end
end
context "when it is a joint purchase and neither of the buyers are over 64" do
let(:record) { FactoryBot.build(:sales_log, jointpur: 1, age1: 43, age2: 33, type: 24) }
it "returns true" do
expect(record.buyers_age_for_old_persons_shared_ownership_invalid?).to be true
end
end
context "when it is a joint purchase and first buyer is under 64 and the second buyers' age is unknown" do
let(:record) { FactoryBot.build(:sales_log, jointpur: 1, age1: 43, age2_known: 1, type: 24) }
it "returns true" do
expect(record.buyers_age_for_old_persons_shared_ownership_invalid?).to be true
end
end
context "when it is a joint purchase and neither of the buyers ages are known" do
let(:record) { FactoryBot.build(:sales_log, jointpur: 1, age1_known: 1, age2_known: 1, type: 24) }
it "returns true" do
expect(record.buyers_age_for_old_persons_shared_ownership_invalid?).to be true
end
end
context "when it is not a joint purchase and the buyer is over 64" do
let(:record) { FactoryBot.build(:sales_log, jointpur: 2, age1: 70, type: 24) }
it "returns false" do
expect(record.buyers_age_for_old_persons_shared_ownership_invalid?).to be false
end
end
context "when it is not a joint purchase and the buyer is under 64" do
let(:record) { FactoryBot.build(:sales_log, jointpur: 2, age1: 20, type: 24) }
it "returns true" do
expect(record.buyers_age_for_old_persons_shared_ownership_invalid?).to be true
end
end
context "when it is not a joint purchase and the buyers age is not known" do
let(:record) { FactoryBot.build(:sales_log, jointpur: 2, age1_known: 1, type: 24) }
it "returns true" do
expect(record.buyers_age_for_old_persons_shared_ownership_invalid?).to be true
end
end
end
end

9
spec/services/bulk_upload/lettings/validator_spec.rb

@ -43,7 +43,14 @@ RSpec.describe BulkUpload::Lettings::Validator do
validator.call
error = BulkUploadError.first
expect(error.row).to eq("7")
expect(error.field).to eql("field_96")
expect(error.error).to eql("blank")
expect(error.tenant_code).to eql("123")
expect(error.property_ref).to be_nil
expect(error.row).to eql("7")
expect(error.cell).to eql("CS7")
expect(error.col).to eql("CS")
end
end

Loading…
Cancel
Save