Browse Source
* Include shared validations in sales log model and run validate_numeric_min_max method * Add non london hard max income validation * Add london income validation * Remove child vlidation because buyer cannot be a child * Add income1_value_check column * Add buyer_1_income_value_check question and page * Update income1_under_soft_min? * Add mortgage and value check column * Add mortgage value check page * Update mortgage_over_soft_max? in soft validateions * Remove unused error messagepull/1088/head
kosiakkatrina
2 years ago
committed by
GitHub
23 changed files with 662 additions and 5 deletions
@ -0,0 +1,21 @@
|
||||
class Form::Sales::Pages::Buyer1IncomeValueCheck < ::Form::Page |
||||
def initialize(id, hsh, subsection) |
||||
super |
||||
@id = "buyer_1_income_value_check" |
||||
@header = "" |
||||
@description = "" |
||||
@subsection = subsection |
||||
@depends_on = [ |
||||
{ |
||||
"income1_under_soft_min?" => true, |
||||
}, |
||||
] |
||||
@informative_text = {} |
||||
end |
||||
|
||||
def questions |
||||
@questions ||= [ |
||||
Form::Sales::Questions::Buyer1IncomeValueCheck.new(nil, nil, self), |
||||
] |
||||
end |
||||
end |
@ -0,0 +1,21 @@
|
||||
class Form::Sales::Pages::MortgageValueCheck < ::Form::Page |
||||
def initialize(id, hsh, subsection) |
||||
super |
||||
@id = "mortgage_value_check" |
||||
@header = "" |
||||
@description = "" |
||||
@subsection = subsection |
||||
@depends_on = [ |
||||
{ |
||||
"mortgage_over_soft_max?" => true, |
||||
}, |
||||
] |
||||
@informative_text = {} |
||||
end |
||||
|
||||
def questions |
||||
@questions ||= [ |
||||
Form::Sales::Questions::MortgageValueCheck.new(nil, nil, self), |
||||
] |
||||
end |
||||
end |
@ -0,0 +1,25 @@
|
||||
class Form::Sales::Questions::Buyer1IncomeValueCheck < ::Form::Question |
||||
def initialize(id, hsh, page) |
||||
super |
||||
@id = "income1_value_check" |
||||
@check_answer_label = "Income confirmation" |
||||
@header = "Are you sure this income is correct?" |
||||
@type = "interruption_screen" |
||||
@answer_options = { |
||||
"0" => { "value" => "Yes" }, |
||||
"1" => { "value" => "No" }, |
||||
} |
||||
@hidden_in_check_answers = { |
||||
"depends_on" => [ |
||||
{ |
||||
"income1_value_check" => 0, |
||||
}, |
||||
{ |
||||
"income1_value_check" => 1, |
||||
}, |
||||
], |
||||
} |
||||
@check_answers_card_number = 1 |
||||
@page = page |
||||
end |
||||
end |
@ -0,0 +1,25 @@
|
||||
class Form::Sales::Questions::MortgageValueCheck < ::Form::Question |
||||
def initialize(id, hsh, page) |
||||
super |
||||
@id = "mortgage_value_check" |
||||
@check_answer_label = "Mortgage confirmation" |
||||
@header = "Are you sure that the mortgage is more than 5 times the income used for the mortgage application?" |
||||
@type = "interruption_screen" |
||||
@answer_options = { |
||||
"0" => { "value" => "Yes" }, |
||||
"1" => { "value" => "No" }, |
||||
} |
||||
@hidden_in_check_answers = { |
||||
"depends_on" => [ |
||||
{ |
||||
"mortgage_value_check" => 0, |
||||
}, |
||||
{ |
||||
"mortgage_value_check" => 1, |
||||
}, |
||||
], |
||||
} |
||||
@check_answers_card_number = 1 |
||||
@page = page |
||||
end |
||||
end |
@ -0,0 +1,14 @@
|
||||
module Validations::Sales::FinancialValidations |
||||
# Validations methods need to be called 'validate_<page_name>' to run on model save |
||||
# 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", hard_max: 90_000) if record.income1 > 90_000 |
||||
elsif record.income1 > 80_000 |
||||
record.errors.add :income1, I18n.t("validations.financial.income1.over_hard_max", hard_max: 80_000) |
||||
end |
||||
end |
||||
end |
||||
end |
@ -0,0 +1,23 @@
|
||||
module Validations::Sales::SoftValidations |
||||
ALLOWED_INCOME_RANGES = { |
||||
1 => OpenStruct.new(soft_min: 5000), |
||||
2 => OpenStruct.new(soft_min: 1500), |
||||
3 => OpenStruct.new(soft_min: 1000), |
||||
5 => OpenStruct.new(soft_min: 2000), |
||||
0 => OpenStruct.new(soft_min: 2000), |
||||
}.freeze |
||||
|
||||
def income1_under_soft_min? |
||||
return false unless ecstat1 && income1 && ALLOWED_INCOME_RANGES[ecstat1] |
||||
|
||||
income1 < ALLOWED_INCOME_RANGES[ecstat1][:soft_min] |
||||
end |
||||
|
||||
def mortgage_over_soft_max? |
||||
return false unless mortgage && inc1mort && inc2mort |
||||
return false if income1_used_for_mortgage? && income1.blank? || income2_used_for_mortgage? && income2.blank? |
||||
|
||||
income_used_for_mortgage = (income1_used_for_mortgage? ? income1 : 0) + (income2_used_for_mortgage? ? income2 : 0) |
||||
mortgage > income_used_for_mortgage * 5 |
||||
end |
||||
end |
@ -1,5 +1,7 @@
|
||||
class AddDetailsKnown1ToSalesLog < ActiveRecord::Migration[7.0] |
||||
change_table :sales_logs, bulk: true do |t| |
||||
t.column :details_known_1, :integer |
||||
def change |
||||
change_table :sales_logs, bulk: true do |t| |
||||
t.column :details_known_1, :integer |
||||
end |
||||
end |
||||
end |
||||
|
@ -0,0 +1,10 @@
|
||||
class AddMortgageAndValueChecks < ActiveRecord::Migration[7.0] |
||||
def change |
||||
change_table :sales_logs, bulk: true do |t| |
||||
t.column :income1_value_check, :integer |
||||
t.column :mortgage, :integer |
||||
t.column :inc2mort, :integer |
||||
t.column :mortgage_value_check, :integer |
||||
end |
||||
end |
||||
end |
@ -0,0 +1,33 @@
|
||||
require "rails_helper" |
||||
|
||||
RSpec.describe Form::Sales::Pages::Buyer1IncomeValueCheck, type: :model do |
||||
subject(:page) { described_class.new(page_id, page_definition, subsection) } |
||||
|
||||
let(:page_id) { nil } |
||||
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[income1_value_check]) |
||||
end |
||||
|
||||
it "has the correct id" do |
||||
expect(page.id).to eq("buyer_1_income_value_check") |
||||
end |
||||
|
||||
it "has the correct header" do |
||||
expect(page.header).to eq("") |
||||
end |
||||
|
||||
it "has correct depends_on" do |
||||
expect(page.depends_on).to eq([ |
||||
{ |
||||
"income1_under_soft_min?" => true, |
||||
}, |
||||
]) |
||||
end |
||||
end |
@ -0,0 +1,33 @@
|
||||
require "rails_helper" |
||||
|
||||
RSpec.describe Form::Sales::Pages::MortgageValueCheck, type: :model do |
||||
subject(:page) { described_class.new(page_id, page_definition, subsection) } |
||||
|
||||
let(:page_id) { nil } |
||||
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[mortgage_value_check]) |
||||
end |
||||
|
||||
it "has the correct id" do |
||||
expect(page.id).to eq("mortgage_value_check") |
||||
end |
||||
|
||||
it "has the correct header" do |
||||
expect(page.header).to eq("") |
||||
end |
||||
|
||||
it "has correct depends_on" do |
||||
expect(page.depends_on).to eq([ |
||||
{ |
||||
"mortgage_over_soft_max?" => true, |
||||
}, |
||||
]) |
||||
end |
||||
end |
@ -0,0 +1,61 @@
|
||||
require "rails_helper" |
||||
|
||||
RSpec.describe Form::Sales::Questions::Buyer1IncomeValueCheck, 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("income1_value_check") |
||||
end |
||||
|
||||
it "has the correct header" do |
||||
expect(question.header).to eq("Are you sure this income is correct?") |
||||
end |
||||
|
||||
it "has the correct check_answer_label" do |
||||
expect(question.check_answer_label).to eq("Income 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(1) |
||||
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" => [ |
||||
{ |
||||
"income1_value_check" => 0, |
||||
}, |
||||
{ |
||||
"income1_value_check" => 1, |
||||
}, |
||||
], |
||||
}) |
||||
end |
||||
end |
@ -0,0 +1,61 @@
|
||||
require "rails_helper" |
||||
|
||||
RSpec.describe Form::Sales::Questions::MortgageValueCheck, 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("mortgage_value_check") |
||||
end |
||||
|
||||
it "has the correct header" do |
||||
expect(question.header).to eq("Are you sure that the mortgage is more than 5 times the income used for the mortgage application?") |
||||
end |
||||
|
||||
it "has the correct check_answer_label" do |
||||
expect(question.check_answer_label).to eq("Mortgage 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(1) |
||||
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" => [ |
||||
{ |
||||
"mortgage_value_check" => 0, |
||||
}, |
||||
{ |
||||
"mortgage_value_check" => 1, |
||||
}, |
||||
], |
||||
}) |
||||
end |
||||
end |
@ -0,0 +1,56 @@
|
||||
require "rails_helper" |
||||
|
||||
RSpec.describe Validations::Sales::FinancialValidations do |
||||
subject(:financial_validator) { validator_class.new } |
||||
|
||||
let(:validator_class) { Class.new { include Validations::Sales::FinancialValidations } } |
||||
|
||||
describe "income validations" do |
||||
let(:record) { FactoryBot.create(:sales_log, ownershipsch: 1) } |
||||
|
||||
context "with shared ownership" do |
||||
context "and non london borough" do |
||||
(0..8).each do |ecstat| |
||||
it "adds an error when buyer 1 income is over hard max for ecstat #{ecstat}" do |
||||
record.income1 = 85_000 |
||||
record.ecstat1 = ecstat |
||||
financial_validator.validate_income1(record) |
||||
expect(record.errors["income1"]) |
||||
.to include(match I18n.t("validations.financial.income1.over_hard_max", hard_max: 80_000)) |
||||
end |
||||
end |
||||
|
||||
it "validates that the income is within the expected range for the tenant’s employment status" do |
||||
record.income1 = 75_000 |
||||
record.ecstat1 = 1 |
||||
financial_validator.validate_income1(record) |
||||
expect(record.errors["income1"]).to be_empty |
||||
end |
||||
end |
||||
|
||||
context "and a london borough" do |
||||
before do |
||||
record.update!(la: "E09000030") |
||||
record.reload |
||||
end |
||||
|
||||
(0..8).each do |ecstat| |
||||
it "adds an error when buyer 1 income is over hard max for ecstat #{ecstat}" do |
||||
record.income1 = 95_000 |
||||
record.ecstat1 = ecstat |
||||
financial_validator.validate_income1(record) |
||||
expect(record.errors["income1"]) |
||||
.to include(match I18n.t("validations.financial.income1.over_hard_max", hard_max: 90_000)) |
||||
end |
||||
end |
||||
|
||||
it "validates that the income is within the expected range for the tenant’s employment status" do |
||||
record.income1 = 85_000 |
||||
record.ecstat1 = 1 |
||||
financial_validator.validate_income1(record) |
||||
expect(record.errors["income1"]).to be_empty |
||||
end |
||||
end |
||||
end |
||||
end |
||||
end |
@ -0,0 +1,204 @@
|
||||
require "rails_helper" |
||||
|
||||
RSpec.describe Validations::Sales::SoftValidations do |
||||
let(:record) { FactoryBot.create(:sales_log) } |
||||
|
||||
describe "income1 min validations" do |
||||
context "when validating soft min" do |
||||
it "returns false if no income1 is given" do |
||||
record.income1 = nil |
||||
expect(record) |
||||
.not_to be_income1_under_soft_min |
||||
end |
||||
|
||||
it "returns false if no ecstat1 is given" do |
||||
record.ecstat1 = nil |
||||
expect(record) |
||||
.not_to be_income1_under_soft_min |
||||
end |
||||
|
||||
[ |
||||
{ |
||||
income1: 4500, |
||||
ecstat1: 1, |
||||
}, |
||||
{ |
||||
income1: 1400, |
||||
ecstat1: 2, |
||||
}, |
||||
{ |
||||
income1: 999, |
||||
ecstat1: 3, |
||||
}, |
||||
{ |
||||
income1: 1899, |
||||
ecstat1: 5, |
||||
}, |
||||
{ |
||||
income1: 1888, |
||||
ecstat1: 0, |
||||
}, |
||||
].each do |test_case| |
||||
it "returns true if income1 is below soft min for ecstat1 #{test_case[:ecstat1]}" do |
||||
record.income1 = test_case[:income1] |
||||
record.ecstat1 = test_case[:ecstat1] |
||||
expect(record) |
||||
.to be_income1_under_soft_min |
||||
end |
||||
end |
||||
|
||||
[ |
||||
{ |
||||
income1: 5001, |
||||
ecstat1: 1, |
||||
}, |
||||
{ |
||||
income1: 1600, |
||||
ecstat1: 2, |
||||
}, |
||||
{ |
||||
income1: 1004, |
||||
ecstat1: 3, |
||||
}, |
||||
{ |
||||
income1: 2899, |
||||
ecstat1: 4, |
||||
}, |
||||
{ |
||||
income1: 2899, |
||||
ecstat1: 5, |
||||
}, |
||||
{ |
||||
income1: 5, |
||||
ecstat1: 6, |
||||
}, |
||||
{ |
||||
income1: 10_888, |
||||
ecstat1: 0, |
||||
}, |
||||
].each do |test_case| |
||||
it "returns false if income1 is over soft min for ecstat1 #{test_case[:ecstat1]}" do |
||||
record.income1 = test_case[:income1] |
||||
record.ecstat1 = test_case[:ecstat1] |
||||
expect(record) |
||||
.not_to be_income1_under_soft_min |
||||
end |
||||
end |
||||
end |
||||
end |
||||
|
||||
describe "mortgage amount validations" do |
||||
context "when validating soft max" do |
||||
it "returns false if no mortgage is given" do |
||||
record.mortgage = nil |
||||
expect(record) |
||||
.not_to be_mortgage_over_soft_max |
||||
end |
||||
|
||||
it "returns false if no inc1mort is given" do |
||||
record.inc1mort = nil |
||||
record.mortgage = 20_000 |
||||
expect(record) |
||||
.not_to be_mortgage_over_soft_max |
||||
end |
||||
|
||||
it "returns false if no inc2mort is given" do |
||||
record.inc1mort = 2 |
||||
record.inc2mort = nil |
||||
record.mortgage = 20_000 |
||||
expect(record) |
||||
.not_to be_mortgage_over_soft_max |
||||
end |
||||
|
||||
it "returns false if no income1 is given and inc1mort is yes" do |
||||
record.inc1mort = 1 |
||||
record.inc2mort = 2 |
||||
record.income1 = nil |
||||
record.mortgage = 20_000 |
||||
expect(record) |
||||
.not_to be_mortgage_over_soft_max |
||||
end |
||||
|
||||
it "returns false if no income2 is given and inc2mort is yes" do |
||||
record.inc1mort = 2 |
||||
record.inc2mort = 1 |
||||
record.income2 = nil |
||||
record.mortgage = 20_000 |
||||
expect(record) |
||||
.not_to be_mortgage_over_soft_max |
||||
end |
||||
|
||||
it "returns true if only income1 is used for morgage and it is less than 1/5 of the morgage" do |
||||
record.inc1mort = 1 |
||||
record.income1 = 10_000 |
||||
record.mortgage = 51_000 |
||||
record.inc2mort = 2 |
||||
expect(record) |
||||
.to be_mortgage_over_soft_max |
||||
end |
||||
|
||||
it "returns false if only income1 is used for morgage and it is more than 1/5 of the morgage" do |
||||
record.inc1mort = 1 |
||||
record.income1 = 10_000 |
||||
record.mortgage = 44_000 |
||||
record.inc2mort = 2 |
||||
expect(record) |
||||
.not_to be_mortgage_over_soft_max |
||||
end |
||||
|
||||
it "returns true if only income2 is used for morgage and it is less than 1/5 of the morgage" do |
||||
record.inc1mort = 2 |
||||
record.inc2mort = 1 |
||||
record.income2 = 10_000 |
||||
record.mortgage = 51_000 |
||||
expect(record) |
||||
.to be_mortgage_over_soft_max |
||||
end |
||||
|
||||
it "returns false if only income2 is used for morgage and it is more than 1/5 of the morgage" do |
||||
record.inc1mort = 2 |
||||
record.inc2mort = 1 |
||||
record.income2 = 10_000 |
||||
record.mortgage = 44_000 |
||||
expect(record) |
||||
.not_to be_mortgage_over_soft_max |
||||
end |
||||
|
||||
it "returns true if income1 and income2 are used for morgage and their sum is less than 1/5 of the morgage" do |
||||
record.inc1mort = 1 |
||||
record.inc2mort = 1 |
||||
record.income1 = 10_000 |
||||
record.income2 = 10_000 |
||||
record.mortgage = 101_000 |
||||
expect(record) |
||||
.to be_mortgage_over_soft_max |
||||
end |
||||
|
||||
it "returns false if income1 and income2 are used for morgage and their sum is more than 1/5 of the morgage" do |
||||
record.inc1mort = 1 |
||||
record.inc2mort = 1 |
||||
record.income1 = 8_000 |
||||
record.income2 = 17_000 |
||||
record.mortgage = 124_000 |
||||
expect(record) |
||||
.not_to be_mortgage_over_soft_max |
||||
end |
||||
|
||||
it "returns true if neither of the incomes are used for morgage and the morgage is more than 0" do |
||||
record.inc1mort = 2 |
||||
record.inc2mort = 2 |
||||
record.mortgage = 124_000 |
||||
expect(record) |
||||
.to be_mortgage_over_soft_max |
||||
end |
||||
|
||||
it "returns true if neither of the incomes are used for morgage and the morgage is 0" do |
||||
record.inc1mort = 2 |
||||
record.inc2mort = 2 |
||||
record.mortgage = 0 |
||||
expect(record) |
||||
.not_to be_mortgage_over_soft_max |
||||
end |
||||
end |
||||
end |
||||
end |
Loading…
Reference in new issue