Browse Source

CLDC-1786 add validations for staircasing transaction (#1235)

* change percent to % so that suffix is consistent with other similar questions

* fix rebase conflicts

* add hard validation that percentage owned after a staircasing transaction cannot be less than the percentage bought in that transaction, with associated tests

* add compound validation to ensure that logs of type older person shared ownership may not have a stairbought value of greater than 75% \n associated tests included

* remove duplicate method and use existing version

* fix rebase conflicts

* ensure schema correct and test of page number correct

* fix form handler test after rebase

* fix tests and ensure schema correct after rebase
pull/1244/head v0.2.36
Arthur Campbell 2 years ago committed by GitHub
parent
commit
648e344af6
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
  1. 27
      app/models/form/sales/pages/staircase_bought_value_check.rb
  2. 2
      app/models/form/sales/questions/staircase_bought.rb
  3. 23
      app/models/form/sales/questions/staircase_bought_value_check.rb
  4. 2
      app/models/form/sales/questions/staircase_owned.rb
  5. 1
      app/models/form/sales/subsections/shared_ownership_scheme.rb
  6. 17
      app/models/validations/sales/financial_validations.rb
  7. 4
      app/models/validations/sales/soft_validations.rb
  8. 4
      config/locales/en.yml
  9. 5
      db/migrate/20230125152916_add_staircase_bought_value_check_to_sales_log.rb
  10. 3
      db/schema.rb
  11. 2
      spec/models/form/sales/questions/staircase_bought_spec.rb
  12. 2
      spec/models/form/sales/questions/staircase_owned_spec.rb
  13. 1
      spec/models/form/sales/subsections/shared_ownership_scheme_spec.rb
  14. 4
      spec/models/form_handler_spec.rb
  15. 59
      spec/models/validations/sales/financial_validations_spec.rb
  16. 22
      spec/models/validations/sales/soft_validations_spec.rb
  17. 6
      spec/models/validations/shared_validations_spec.rb

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

@ -0,0 +1,27 @@
class Form::Sales::Pages::StaircaseBoughtValueCheck < ::Form::Page
def initialize(id, hsh, subsection)
super
@id = "staircase_bought_value_check"
@depends_on = [
{
"staircase_bought_above_fifty?" => true,
},
]
@title_text = {
"translation" => "soft_validations.staircase_bought_seems_high",
"arguments" => [
{
"key" => "stairbought",
"i18n_template" => "percentage",
},
],
}
@informative_text = {}
end
def questions
@questions ||= [
Form::Sales::Questions::StaircaseBoughtValueCheck.new(nil, nil, self),
]
end
end

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

@ -8,6 +8,6 @@ class Form::Sales::Questions::StaircaseBought < ::Form::Question
@width = 5 @width = 5
@min = 0 @min = 0
@max = 100 @max = 100
@suffix = " percent" @suffix = "%"
end end
end end

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

@ -0,0 +1,23 @@
class Form::Sales::Questions::StaircaseBoughtValueCheck < ::Form::Question
def initialize(id, hsh, page)
super
@id = "staircase_bought_value_check"
@check_answer_label = "Percentage bought 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" => [
{
"staircase_bought_value_check" => 0,
},
{
"staircase_bought_value_check" => 1,
},
],
}
end
end

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

@ -8,6 +8,6 @@ class Form::Sales::Questions::StaircaseOwned < ::Form::Question
@width = 5 @width = 5
@min = 0 @min = 0
@max = 100 @max = 100
@suffix = " percent" @suffix = "%"
end end
end end

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

@ -11,6 +11,7 @@ class Form::Sales::Subsections::SharedOwnershipScheme < ::Form::Subsection
Form::Sales::Pages::LivingBeforePurchase.new("living_before_purchase_shared_ownership", nil, self), Form::Sales::Pages::LivingBeforePurchase.new("living_before_purchase_shared_ownership", nil, self),
Form::Sales::Pages::Staircase.new(nil, nil, self), Form::Sales::Pages::Staircase.new(nil, nil, self),
Form::Sales::Pages::AboutStaircase.new(nil, nil, self), Form::Sales::Pages::AboutStaircase.new(nil, nil, self),
Form::Sales::Pages::StaircaseBoughtValueCheck.new(nil, nil, self),
Form::Sales::Pages::Resale.new(nil, nil, self), Form::Sales::Pages::Resale.new(nil, nil, self),
Form::Sales::Pages::ExchangeDate.new(nil, nil, self), Form::Sales::Pages::ExchangeDate.new(nil, nil, self),
Form::Sales::Pages::HandoverDate.new(nil, nil, self), Form::Sales::Pages::HandoverDate.new(nil, nil, self),

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

@ -27,4 +27,21 @@ module Validations::Sales::FinancialValidations
record.errors.add :cashdis, I18n.t("validations.financial.cash_discount_invalid") record.errors.add :cashdis, I18n.t("validations.financial.cash_discount_invalid")
end end
end end
def validate_percentage_bought_not_greater_than_percentage_owned(record)
return unless record.stairbought && record.stairowned
if record.stairbought > record.stairowned
record.errors.add :stairowned, I18n.t("validations.financial.staircasing.percentage_bought_must_be_greater_than_percentage_owned")
end
end
def validate_percentage_owned_not_too_much_if_older_person(record)
return unless record.old_persons_shared_ownership? && record.stairowned
if record.stairowned > 75
record.errors.add :stairowned, I18n.t("validations.financial.staircasing.older_person_percentage_owned_maximum_75")
record.errors.add :type, I18n.t("validations.financial.staircasing.older_person_percentage_owned_maximum_75")
end
end
end end

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

@ -13,6 +13,10 @@ module Validations::Sales::SoftValidations
income1 < ALLOWED_INCOME_RANGES[ecstat1][:soft_min] income1 < ALLOWED_INCOME_RANGES[ecstat1][:soft_min]
end end
def staircase_bought_above_fifty?
stairbought && stairbought > 50
end
def mortgage_over_soft_max? def mortgage_over_soft_max?
return false unless mortgage && inc1mort && inc2mort return false unless mortgage && inc1mort && inc2mort
return false if income1_used_for_mortgage? && income1.blank? || income2_used_for_mortgage? && income2.blank? return false if income1_used_for_mortgage? && income1.blank? || income2_used_for_mortgage? && income2.blank?

4
config/locales/en.yml

@ -277,6 +277,10 @@ en:
out_of_range: "Household rent and other charges must be between %{min_chcharge} and %{max_chcharge} if paying %{period}" out_of_range: "Household rent and other charges must be between %{min_chcharge} and %{max_chcharge} if paying %{period}"
not_provided: "Enter how much rent and other charges the household pays %{period}" not_provided: "Enter how much rent and other charges the household pays %{period}"
cash_discount_invalid: "Cash discount must be £0 - £999,999" cash_discount_invalid: "Cash discount must be £0 - £999,999"
staircasing:
percentage_bought_must_be_greater_than_percentage_owned: "Total percentage buyer now owns must be more than percentage bought in this transaction"
older_person_percentage_owned_maximum_75: "Percentage cannot be above 75% under Older Person's Shared Ownership"
household: household:
reasonpref: reasonpref:
not_homeless: "Answer cannot be ‘homeless or about to lose their home’ as the tenant was not homeless immediately prior to this letting" not_homeless: "Answer cannot be ‘homeless or about to lose their home’ as the tenant was not homeless immediately prior to this letting"

5
db/migrate/20230125152916_add_staircase_bought_value_check_to_sales_log.rb

@ -0,0 +1,5 @@
class AddStaircaseBoughtValueCheckToSalesLog < ActiveRecord::Migration[7.0]
def change
add_column :sales_logs, :staircase_bought_value_check, :integer
end
end

3
db/schema.rb

@ -504,9 +504,10 @@ ActiveRecord::Schema[7.0].define(version: 2023_01_26_145529) do
t.integer "retirement_value_check" t.integer "retirement_value_check"
t.integer "hodate_check" t.integer "hodate_check"
t.integer "extrabor_value_check" t.integer "extrabor_value_check"
t.integer "grant_value_check"
t.integer "staircase_bought_value_check"
t.integer "deposit_and_mortgage_value_check" t.integer "deposit_and_mortgage_value_check"
t.integer "shared_ownership_deposit_value_check" t.integer "shared_ownership_deposit_value_check"
t.integer "grant_value_check"
t.integer "old_persons_shared_ownership_value_check" t.integer "old_persons_shared_ownership_value_check"
t.index ["bulk_upload_id"], name: "index_sales_logs_on_bulk_upload_id" t.index ["bulk_upload_id"], name: "index_sales_logs_on_bulk_upload_id"
t.index ["created_by_id"], name: "index_sales_logs_on_created_by_id" t.index ["created_by_id"], name: "index_sales_logs_on_created_by_id"

2
spec/models/form/sales/questions/staircase_bought_spec.rb

@ -44,7 +44,7 @@ RSpec.describe Form::Sales::Questions::StaircaseBought, type: :model do
end end
it "has correct suffix" do it "has correct suffix" do
expect(question.suffix).to eq(" percent") expect(question.suffix).to eq("%")
end end
it "has correct min" do it "has correct min" do

2
spec/models/form/sales/questions/staircase_owned_spec.rb

@ -44,7 +44,7 @@ RSpec.describe Form::Sales::Questions::StaircaseOwned, type: :model do
end end
it "has correct suffix" do it "has correct suffix" do
expect(question.suffix).to eq(" percent") expect(question.suffix).to eq("%")
end end
it "has correct min" do it "has correct min" do

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

@ -17,6 +17,7 @@ RSpec.describe Form::Sales::Subsections::SharedOwnershipScheme, type: :model do
living_before_purchase_shared_ownership living_before_purchase_shared_ownership
staircasing staircasing
about_staircasing about_staircasing
staircase_bought_value_check
resale resale
exchange_contracts exchange_contracts
handover_date handover_date

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 it "is able to load a current sales form" do
form = form_handler.get_form("current_sales") form = form_handler.get_form("current_sales")
expect(form).to be_a(Form) expect(form).to be_a(Form)
expect(form.pages.count).to eq(197) expect(form.pages.count).to eq(198)
expect(form.name).to eq("2022_2023_sales") expect(form.name).to eq("2022_2023_sales")
end end
it "is able to load a previous sales form" do it "is able to load a previous sales form" do
form = form_handler.get_form("previous_sales") form = form_handler.get_form("previous_sales")
expect(form).to be_a(Form) expect(form).to be_a(Form)
expect(form.pages.count).to eq(197) expect(form.pages.count).to eq(198)
expect(form.name).to eq("2021_2022_sales") expect(form.name).to eq("2021_2022_sales")
end end
end end

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

@ -99,4 +99,63 @@ RSpec.describe Validations::Sales::FinancialValidations do
expect(record.errors["cashdis"]).to be_empty expect(record.errors["cashdis"]).to be_empty
end end
end end
describe "#validate_percentage_bought_not_greater_than_percentage_owned" do
let(:record) { FactoryBot.create(:sales_log) }
it "does not add an error if the percentage bought is less than the percentage owned" do
record.stairbought = 20
record.stairowned = 40
financial_validator.validate_percentage_bought_not_greater_than_percentage_owned(record)
expect(record.errors["stairbought"]).to be_empty
expect(record.errors["stairowned"]).to be_empty
end
it "does not add an error if the percentage bought is equal to the percentage owned" do
record.stairbought = 30
record.stairowned = 30
financial_validator.validate_percentage_bought_not_greater_than_percentage_owned(record)
expect(record.errors["stairbought"]).to be_empty
expect(record.errors["stairowned"]).to be_empty
end
it "adds an error to stairowned and not stairbought if the percentage bought is more than the percentage owned" do
record.stairbought = 50
record.stairowned = 40
financial_validator.validate_percentage_bought_not_greater_than_percentage_owned(record)
expect(record.errors["stairowned"]).to include(match I18n.t("validations.financial.staircasing.percentage_bought_must_be_greater_than_percentage_owned"))
end
end
describe "#validate_percentage_owned_not_too_much_if_older_person" do
let(:record) { FactoryBot.create(:sales_log) }
context "when log type is not older persons shared ownership" do
it "does not add an error when percentage owned after staircasing transaction exceeds 75%" do
record.type = 2
record.stairowned = 80
financial_validator.validate_percentage_owned_not_too_much_if_older_person(record)
expect(record.errors["stairowned"]).to be_empty
expect(record.errors["type"]).to be_empty
end
end
context "when log type is older persons shared ownership" do
it "does not add an error when percentage owned after staircasing transaction is less than 75%" do
record.type = 24
record.stairowned = 50
financial_validator.validate_percentage_owned_not_too_much_if_older_person(record)
expect(record.errors["stairowned"]).to be_empty
expect(record.errors["type"]).to be_empty
end
it "adds an error when percentage owned after staircasing transaction exceeds 75%" do
record.type = 24
record.stairowned = 90
financial_validator.validate_percentage_owned_not_too_much_if_older_person(record)
expect(record.errors["stairowned"]).to include(match I18n.t("validations.financial.staircasing.older_person_percentage_owned_maximum_75"))
expect(record.errors["type"]).to include(match I18n.t("validations.financial.staircasing.older_person_percentage_owned_maximum_75"))
end
end
end
end end

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

@ -367,7 +367,7 @@ RSpec.describe Validations::Sales::SoftValidations do
.to be_deposit_over_soft_max .to be_deposit_over_soft_max
end end
it "returns fals if deposit is less than 4/3 of savings" do it "returns false if deposit is less than 4/3 of savings" do
record.deposit = 7_999 record.deposit = 7_999
record.savings = 6_000 record.savings = 6_000
expect(record) expect(record)
@ -573,4 +573,24 @@ RSpec.describe Validations::Sales::SoftValidations do
expect(record).not_to be_grant_outside_common_range expect(record).not_to be_grant_outside_common_range
end end
end end
describe "#staircase_bought_above_fifty" do
it "returns false when stairbought is not set" do
record.stairbought = nil
expect(record).not_to be_staircase_bought_above_fifty
end
it "returns false when stairbought is below fifty" do
record.stairbought = 40
expect(record).not_to be_staircase_bought_above_fifty
end
it "returns true when stairbought is above fifty" do
record.stairbought = 70
expect(record).to be_staircase_bought_above_fifty
end
end
end end

6
spec/models/validations/shared_validations_spec.rb

@ -70,11 +70,11 @@ RSpec.describe Validations::SharedValidations do
end end
context "when validating percent" do context "when validating percent" do
it "validates that % suffix is added in the error message" do it "validates that suffixes are added in the error message" do
sales_record.stairbought = "random" sales_record.stairbought = 150
shared_validator.validate_numeric_min_max(sales_record) shared_validator.validate_numeric_min_max(sales_record)
expect(sales_record.errors["stairbought"]) expect(sales_record.errors["stairbought"])
.to include(match I18n.t("validations.numeric.valid", field: "Percentage bought in this staircasing transaction", min: "0 percent", max: "100 percent")) .to include(match I18n.t("validations.numeric.valid", field: "Percentage bought in this staircasing transaction", min: "0%", max: "100%"))
end end
end end

Loading…
Cancel
Save