Browse Source

CLDC-3176 Make deposit dynamically optional (#2210)

* Update optional hint text for deposit in 24/25

* Make deposit dynamically optional, update BU

* Refactor conditional page

* Add validation
pull/2234/head
kosiakkatrina 11 months ago committed by GitHub
parent
commit
ea1a7b7f54
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
  1. 17
      app/models/form/sales/pages/about_deposit_with_discount.rb
  2. 20
      app/models/form/sales/pages/about_deposit_without_discount.rb
  3. 12
      app/models/form/sales/questions/deposit_amount.rb
  4. 2
      app/models/form/sales/subsections/discounted_ownership_scheme.rb
  5. 2
      app/models/form/sales/subsections/outright_sale.rb
  6. 8
      app/models/form/sales/subsections/shared_ownership_scheme.rb
  7. 5
      app/models/sales_log.rb
  8. 10
      app/models/validations/sales/sale_information_validations.rb
  9. 8
      app/services/bulk_upload/sales/year2024/row_parser.rb
  10. 2
      config/locales/en.yml
  11. 40
      spec/models/form/sales/pages/about_deposit_with_discount_spec.rb
  12. 44
      spec/models/form/sales/pages/about_deposit_without_discount_spec.rb
  13. 10
      spec/models/form/sales/questions/deposit_amount_spec.rb
  14. 4
      spec/models/form/sales/subsections/shared_ownership_scheme_spec.rb
  15. 44
      spec/models/validations/sales/sale_information_validations_spec.rb
  16. 30
      spec/services/bulk_upload/sales/year2024/row_parser_spec.rb

17
app/models/form/sales/pages/about_deposit_with_discount.rb

@ -1,15 +1,22 @@
class Form::Sales::Pages::AboutDepositWithDiscount < ::Form::Page
def initialize(id, hsh, subsection)
super
@id = "about_deposit_with_discount"
def initialize(id, hsh, subsection, optional:)
super(id, hsh, subsection)
@header = "About the deposit"
@depends_on = [{ "is_type_discount?" => true }]
@optional = optional
end
def questions
@questions ||= [
Form::Sales::Questions::DepositAmount.new(nil, nil, self, ownershipsch: 1),
Form::Sales::Questions::DepositAmount.new(nil, nil, self, ownershipsch: 1, optional: @optional),
Form::Sales::Questions::DepositDiscount.new(nil, nil, self),
]
end
def depends_on
if form.start_year_after_2024?
[{ "is_type_discount?" => true, "stairowned_100?" => @optional }]
else
[{ "is_type_discount?" => true }]
end
end
end

20
app/models/form/sales/pages/about_deposit_without_discount.rb

@ -1,16 +1,26 @@
class Form::Sales::Pages::AboutDepositWithoutDiscount < ::Form::Page
def initialize(id, hsh, subsection, ownershipsch:)
def initialize(id, hsh, subsection, ownershipsch:, optional:)
super(id, hsh, subsection)
@header = "About the deposit"
@depends_on = [{ "is_type_discount?" => false, "ownershipsch" => 1 },
{ "ownershipsch" => 2 },
{ "ownershipsch" => 3, "mortgageused" => 1 }]
@ownershipsch = ownershipsch
@optional = optional
end
def questions
@questions ||= [
Form::Sales::Questions::DepositAmount.new(nil, nil, self, ownershipsch: @ownershipsch),
Form::Sales::Questions::DepositAmount.new(nil, nil, self, ownershipsch: @ownershipsch, optional: @optional),
]
end
def depends_on
if form.start_year_after_2024?
[{ "is_type_discount?" => false, "ownershipsch" => 1, "stairowned_100?" => @optional },
{ "ownershipsch" => 2 },
{ "ownershipsch" => 3, "mortgageused" => 1 }]
else
[{ "is_type_discount?" => false, "ownershipsch" => 1 },
{ "ownershipsch" => 2 },
{ "ownershipsch" => 3, "mortgageused" => 1 }]
end
end
end

12
app/models/form/sales/questions/deposit_amount.rb

@ -1,5 +1,5 @@
class Form::Sales::Questions::DepositAmount < ::Form::Question
def initialize(id, hsh, subsection, ownershipsch:)
def initialize(id, hsh, subsection, ownershipsch:, optional:)
super(id, hsh, subsection)
@id = "deposit"
@check_answer_label = "Cash deposit"
@ -10,10 +10,10 @@ class Form::Sales::Questions::DepositAmount < ::Form::Question
@step = 1
@width = 5
@prefix = "£"
@hint_text = "Enter the total cash sum paid by the buyer towards the property that was not funded by the mortgage"
@derived = true
@ownershipsch = ownershipsch
@question_number = question_number
@optional = optional
end
def selected_answer_option_is_derived?(_log)
@ -30,4 +30,12 @@ class Form::Sales::Questions::DepositAmount < ::Form::Question
116
end
end
def hint_text
if @optional
"Enter the total cash sum paid by the buyer towards the property that was not funded by the mortgage. As this is a fully staircased sale this question is optional. If you do not have the information available click save and continue"
else
"Enter the total cash sum paid by the buyer towards the property that was not funded by the mortgage"
end
end
end

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

@ -31,7 +31,7 @@ class Form::Sales::Subsections::DiscountedOwnershipScheme < ::Form::Subsection
Form::Sales::Pages::MortgageLength.new("mortgage_length_discounted_ownership", nil, self, ownershipsch: 2),
Form::Sales::Pages::ExtraBorrowing.new("extra_borrowing_discounted_ownership", nil, self, ownershipsch: 2),
Form::Sales::Pages::ExtraBorrowingValueCheck.new("extra_borrowing_value_check", nil, self),
Form::Sales::Pages::AboutDepositWithoutDiscount.new("about_deposit_discounted_ownership", nil, self, ownershipsch: 2),
Form::Sales::Pages::AboutDepositWithoutDiscount.new("about_deposit_discounted_ownership", nil, self, ownershipsch: 2, optional: false),
Form::Sales::Pages::ExtraBorrowingValueCheck.new("extra_borrowing_deposit_value_check", nil, self),
Form::Sales::Pages::DepositValueCheck.new("discounted_ownership_deposit_value_check", nil, self),
Form::Sales::Pages::DepositAndMortgageValueCheck.new("discounted_ownership_deposit_and_mortgage_value_check_after_deposit", nil, self),

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

@ -18,7 +18,7 @@ class Form::Sales::Subsections::OutrightSale < ::Form::Subsection
(Form::Sales::Pages::MortgageLenderOther.new("mortgage_lender_other_outright_sale", nil, self, ownershipsch: 3) unless form.start_year_after_2024?),
Form::Sales::Pages::MortgageLength.new("mortgage_length_outright_sale", nil, self, ownershipsch: 3),
Form::Sales::Pages::ExtraBorrowing.new("extra_borrowing_outright_sale", nil, self, ownershipsch: 3),
Form::Sales::Pages::AboutDepositWithoutDiscount.new("about_deposit_outright_sale", nil, self, ownershipsch: 3),
Form::Sales::Pages::AboutDepositWithoutDiscount.new("about_deposit_outright_sale", nil, self, ownershipsch: 3, optional: false),
Form::Sales::Pages::DepositValueCheck.new("outright_sale_deposit_value_check", nil, self),
leasehold_charge_pages,
Form::Sales::Pages::MonthlyChargesValueCheck.new("monthly_charges_outright_sale_value_check", nil, self),

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

@ -37,14 +37,16 @@ class Form::Sales::Subsections::SharedOwnershipScheme < ::Form::Subsection
Form::Sales::Pages::MortgageLenderOther.new("mortgage_lender_other_shared_ownership", nil, self, ownershipsch: 1),
Form::Sales::Pages::MortgageLength.new("mortgage_length_shared_ownership", nil, self, ownershipsch: 1),
Form::Sales::Pages::ExtraBorrowing.new("extra_borrowing_shared_ownership", nil, self, ownershipsch: 1),
Form::Sales::Pages::AboutDepositWithDiscount.new(nil, nil, self),
Form::Sales::Pages::AboutDepositWithoutDiscount.new("about_deposit_shared_ownership", nil, self, ownershipsch: 1),
Form::Sales::Pages::AboutDepositWithDiscount.new("about_deposit_with_discount", nil, self, optional: false),
(Form::Sales::Pages::AboutDepositWithDiscount.new("about_deposit_with_discount_optional", nil, self, optional: true) if form.start_year_after_2024?),
Form::Sales::Pages::AboutDepositWithoutDiscount.new("about_deposit_shared_ownership", nil, self, ownershipsch: 1, optional: false),
(Form::Sales::Pages::AboutDepositWithoutDiscount.new("about_deposit_shared_ownership_optional", nil, self, ownershipsch: 1, optional: true) if form.start_year_after_2024?),
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, ownershipsch: 1),
Form::Sales::Pages::MonthlyChargesValueCheck.new("monthly_charges_shared_ownership_value_check", nil, self),
]
].compact
end
def displayed_in_tasklist?(log)

5
app/models/sales_log.rb

@ -121,6 +121,7 @@ class SalesLog < Log
not_required << "proplen" if proplen_optional?
not_required << "mortlen" if mortlen_optional?
not_required << "frombeds" if frombeds_optional?
not_required << "deposit" if form.start_year_after_2024? && stairowned_100?
not_required |= %w[address_line2 county postcode_full] if saledate && collection_start_year_for_date(saledate) >= 2023
@ -495,4 +496,8 @@ class SalesLog < Log
def is_not_staircasing?
staircase == 2 || staircase == 3
end
def stairowned_100?
stairowned == 100
end
end

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

@ -110,4 +110,14 @@ module Validations::Sales::SaleInformationValidations
end
end
end
def validate_mortgage_used_and_stairbought(record)
return unless record.stairowned && record.mortgageused
return unless record.saledate && record.form.start_year_after_2024?
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
end

8
app/services/bulk_upload/sales/year2024/row_parser.rb

@ -341,6 +341,14 @@ class BulkUpload::Sales::Year2024::RowParser
},
on: :before_log
validates :field_103,
inclusion: {
in: [1, 2],
if: proc { field_88 != 100 },
question: QUESTIONS[:field_103],
},
on: :before_log
validates :field_9,
presence: {
message: I18n.t("validations.not_answered", question: "type of shared ownership sale"),

2
config/locales/en.yml

@ -623,6 +623,8 @@ 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: "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."
stairowned:
mortgageused_dont_know: "The percentage owned has to be 100% if the mortgage used is 'Don’t know'"
merge_request:
organisation_part_of_another_merge: "This organisation is part of another merge - select a different one"
organisation_not_selected: "Select an organisation from the search list"

40
spec/models/form/sales/pages/about_deposit_with_discount_spec.rb

@ -1,12 +1,16 @@
require "rails_helper"
RSpec.describe Form::Sales::Pages::AboutDepositWithDiscount, type: :model do
subject(:page) { described_class.new(page_id, page_definition, subsection) }
subject(:page) { described_class.new(page_id, page_definition, subsection, optional: false) }
let(:page_id) { nil }
let(:page_id) { "about_deposit_with_discount" }
let(:page_definition) { nil }
let(:subsection) { instance_double(Form::Subsection) }
before do
allow(subsection).to receive(:form).and_return(instance_double(Form, start_year_after_2024?: false))
end
it "has correct subsection" do
expect(page.subsection).to eq(subsection)
end
@ -32,4 +36,36 @@ RSpec.describe Form::Sales::Pages::AboutDepositWithDiscount, type: :model do
[{ "is_type_discount?" => true }],
)
end
context "when optional" do
subject(:page) { described_class.new(page_id, page_definition, subsection, optional: true) }
it "has correct depends_on" do
expect(page.depends_on).to eq(
[{ "is_type_discount?" => true }],
)
end
end
context "when it's a 2024 form" do
before do
allow(subsection).to receive(:form).and_return(instance_double(Form, start_year_after_2024?: true))
end
it "has correct depends_on" do
expect(page.depends_on).to eq(
[{ "is_type_discount?" => true, "stairowned_100?" => false }],
)
end
context "and optional" do
subject(:page) { described_class.new(page_id, page_definition, subsection, optional: true) }
it "has correct depends_on" do
expect(page.depends_on).to eq(
[{ "is_type_discount?" => true, "stairowned_100?" => true }],
)
end
end
end
end

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

@ -1,12 +1,16 @@
require "rails_helper"
RSpec.describe Form::Sales::Pages::AboutDepositWithoutDiscount, type: :model do
subject(:page) { described_class.new(page_id, page_definition, subsection, ownershipsch: 1) }
subject(:page) { described_class.new(page_id, page_definition, subsection, ownershipsch: 1, optional: false) }
let(:page_id) { nil }
let(:page_definition) { nil }
let(:subsection) { instance_double(Form::Subsection) }
before do
allow(subsection).to receive(:form).and_return(instance_double(Form, start_year_after_2024?: false))
end
it "has correct subsection" do
expect(page.subsection).to eq(subsection)
end
@ -34,4 +38,42 @@ RSpec.describe Form::Sales::Pages::AboutDepositWithoutDiscount, type: :model do
{ "ownershipsch" => 3, "mortgageused" => 1 }],
)
end
context "when optional is true" do
subject(:page) { described_class.new(page_id, page_definition, subsection, ownershipsch: 1, optional: true) }
it "has correct depends_on" do
expect(page.depends_on).to eq(
[{ "is_type_discount?" => false, "ownershipsch" => 1 },
{ "ownershipsch" => 2 },
{ "ownershipsch" => 3, "mortgageused" => 1 }],
)
end
end
context "when it's a 2024 form" do
before do
allow(subsection).to receive(:form).and_return(instance_double(Form, start_year_after_2024?: true))
end
it "has correct depends_on" do
expect(page.depends_on).to eq(
[{ "is_type_discount?" => false, "ownershipsch" => 1, "stairowned_100?" => false },
{ "ownershipsch" => 2 },
{ "ownershipsch" => 3, "mortgageused" => 1 }],
)
end
context "and optional is true" do
subject(:page) { described_class.new(page_id, page_definition, subsection, ownershipsch: 1, optional: true) }
it "has correct depends_on" do
expect(page.depends_on).to eq(
[{ "is_type_discount?" => false, "ownershipsch" => 1, "stairowned_100?" => true },
{ "ownershipsch" => 2 },
{ "ownershipsch" => 3, "mortgageused" => 1 }],
)
end
end
end
end

10
spec/models/form/sales/questions/deposit_amount_spec.rb

@ -1,7 +1,7 @@
require "rails_helper"
RSpec.describe Form::Sales::Questions::DepositAmount, type: :model do
subject(:question) { described_class.new(question_id, question_definition, page, ownershipsch: 1) }
subject(:question) { described_class.new(question_id, question_definition, page, ownershipsch: 1, optional: false) }
let(:question_id) { nil }
let(:question_definition) { nil }
@ -50,4 +50,12 @@ RSpec.describe Form::Sales::Questions::DepositAmount, type: :model do
it "has correct max" do
expect(question.max).to eq(999_999)
end
context "when optional iis true" do
subject(:question) { described_class.new(question_id, question_definition, page, ownershipsch: 1, optional: true) }
it "has a correct hint_text" do
expect(question.hint_text).to eq("Enter the total cash sum paid by the buyer towards the property that was not funded by the mortgage. As this is a fully staircased sale this question is optional. If you do not have the information available click save and continue")
end
end
end

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

@ -7,6 +7,10 @@ RSpec.describe Form::Sales::Subsections::SharedOwnershipScheme, type: :model do
let(:subsection_definition) { nil }
let(:section) { instance_double(Form::Sales::Sections::SaleInformation) }
before do
allow(section).to receive(:form).and_return(instance_double(Form, start_year_after_2024?: false))
end
it "has correct section" do
expect(shared_ownership_scheme.section).to eq(section)
end

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

@ -756,4 +756,48 @@ RSpec.describe Validations::Sales::SaleInformationValidations do
end
end
end
describe "#validate_mortgage_used_and_stairbought" do
let(:now) { Time.zone.local(2024, 4, 4) }
before do
Timecop.freeze(now)
Singleton.__init__(FormHandler)
end
after do
Timecop.return
Singleton.__init__(FormHandler)
end
context "when mortgageused don't know" do
let(:record) { build(:sales_log, ownershipsch: 1, type: 9, saledate: now, mortgageused: 3) }
it "does not add an error if stairowned 100" do
record.stairowned = 100
sale_information_validator.validate_mortgage_used_and_stairbought(record)
expect(record.errors).to be_empty
end
it "adds an error if stairowned is not 100" do
record.stairowned = 90
sale_information_validator.validate_mortgage_used_and_stairbought(record)
expect(record.errors[:stairowned]).to include("The percentage owned has to be 100% if the mortgage used is 'Don’t know'")
expect(record.errors[:mortgageused]).to include("The percentage owned has to be 100% if the mortgage used is 'Don’t know'")
end
end
context "when the collection year is before 2024" do
let(:record) { build(:sales_log, ownershipsch: 1, type: 9, saledate: now, mortgageused: 3, stairowned: 90) }
let(:now) { Time.zone.local(2023, 4, 4) }
it "does not add an error" do
sale_information_validator.validate_mortgage_used_and_stairbought(record)
expect(record.errors).to be_empty
end
end
end
end

30
spec/services/bulk_upload/sales/year2024/row_parser_spec.rb

@ -975,6 +975,36 @@ RSpec.describe BulkUpload::Sales::Year2024::RowParser do
end
end
describe "#field_103" do # shared ownership mortgageused
context "when invalid value" do
let(:attributes) { setup_section_params.merge(field_103: "4") }
it "returns correct errors" do
expect(parser.errors[:field_103]).to include("Enter a valid value for Was a mortgage used for the purchase of this property? - Shared ownership")
end
end
context "when value is 3 and stairowned is not 100" do
let(:attributes) { setup_section_params.merge(field_103: "3", field_86: "1", field_87: "50", field_88: "99", field_109: nil) }
it "returns correct errors" do
expect(parser.errors[:field_103]).to include("Enter a valid value for Was a mortgage used for the purchase of this property? - Shared ownership")
end
end
context "when value is 3 and stairowned is 100" do
let(:attributes) { setup_section_params.merge(field_103: "3", field_86: "1", field_87: "50", field_88: "100", field_109: nil) }
it "does not add errors and sets mortgage used to 3" do
expect(parser.log.mortgageused).to be(3)
expect(parser.log.stairowned).to be(100)
expect(parser.log.deposit).to be(nil)
expect(parser.errors[:field_103]).to be_empty
expect(parser.errors[:field_109]).to be_empty
end
end
end
describe "soft validations" do
context "when soft validation is triggered" do
let(:attributes) { valid_attributes.merge({ field_31: 22, field_35: 5 }) }

Loading…
Cancel
Save