Browse Source

Merge branch 'main' into ReasonOther

pull/2236/head
Rachael Booth 2 years ago
parent
commit
c753f04eb2
  1. 2
      Dockerfile
  2. 6
      app/models/derived_variables/lettings_log_variables.rb
  3. 2
      app/models/form/lettings/pages/property_number_of_bedrooms.rb
  4. 5
      app/models/form/lettings/questions/beds.rb
  5. 2
      app/models/form/lettings/questions/nationality_all_group.rb
  6. 17
      app/models/form/sales/pages/about_deposit_with_discount.rb
  7. 20
      app/models/form/sales/pages/about_deposit_without_discount.rb
  8. 12
      app/models/form/sales/questions/deposit_amount.rb
  9. 9
      app/models/form/sales/questions/nationality_all_group.rb
  10. 2
      app/models/form/sales/subsections/discounted_ownership_scheme.rb
  11. 2
      app/models/form/sales/subsections/outright_sale.rb
  12. 8
      app/models/form/sales/subsections/shared_ownership_scheme.rb
  13. 4
      app/models/lettings_log.rb
  14. 5
      app/models/sales_log.rb
  15. 2
      app/models/validations/property_validations.rb
  16. 10
      app/models/validations/sales/sale_information_validations.rb
  17. 2
      app/services/bulk_upload/lettings/year2024/row_parser.rb
  18. 8
      app/services/bulk_upload/sales/year2024/row_parser.rb
  19. 2
      config/locales/en.yml
  20. 33
      spec/models/form/lettings/pages/property_number_of_bedrooms_spec.rb
  21. 65
      spec/models/form/lettings/questions/beds_spec.rb
  22. 2
      spec/models/form/lettings/questions/nationality_all_group_spec.rb
  23. 40
      spec/models/form/sales/pages/about_deposit_with_discount_spec.rb
  24. 44
      spec/models/form/sales/pages/about_deposit_without_discount_spec.rb
  25. 10
      spec/models/form/sales/questions/deposit_amount_spec.rb
  26. 4
      spec/models/form/sales/questions/nationality_all_group_spec.rb
  27. 4
      spec/models/form/sales/subsections/shared_ownership_scheme_spec.rb
  28. 44
      spec/models/validations/sales/sale_information_validations_spec.rb
  29. 18
      spec/services/bulk_upload/lettings/year2024/row_parser_spec.rb
  30. 30
      spec/services/bulk_upload/sales/year2024/row_parser_spec.rb

2
Dockerfile

@ -10,7 +10,7 @@ RUN apk add --update --no-cache tzdata && \
# build-base: compilation tools for bundle # build-base: compilation tools for bundle
# yarn: node package manager # yarn: node package manager
# postgresql-dev: postgres driver and libraries # postgresql-dev: postgres driver and libraries
RUN apk add --no-cache build-base=0.5-r3 nodejs-current=20.8.1-r0 yarn=1.22.19-r0 postgresql13-dev=13.13-r0 git=2.40.1-r0 bash=5.2.15-r5 RUN apk add --no-cache build-base=0.5-r3 nodejs-current=20.8.1-r0 yarn=1.22.19-r0 postgresql13-dev=13.14-r0 git=2.40.1-r0 bash=5.2.15-r5
# Bundler version should be the same version as what the Gemfile.lock was bundled with # Bundler version should be the same version as what the Gemfile.lock was bundled with
RUN gem install bundler:2.3.14 --no-document RUN gem install bundler:2.3.14 --no-document

6
app/models/derived_variables/lettings_log_variables.rb

@ -91,6 +91,9 @@ module DerivedVariables::LettingsLogVariables
self.prevten = 30 if owning_organisation&.provider_type == "LA" self.prevten = 30 if owning_organisation&.provider_type == "LA"
end end
end end
if form.start_year_after_2024? && is_bedsit?
self.beds = 1
end
child_under_16_constraints! child_under_16_constraints!
@ -179,6 +182,9 @@ private
self.wchair = nil self.wchair = nil
self.location_id = nil self.location_id = nil
end end
if form.start_year_after_2024? && (unittype_gn_changed? && unittype_gn_was == 2)
self.beds = nil
end
end end
def get_totelder def get_totelder

2
app/models/form/lettings/pages/property_number_of_bedrooms.rb

@ -2,7 +2,7 @@ class Form::Lettings::Pages::PropertyNumberOfBedrooms < ::Form::Page
def initialize(id, hsh, subsection) def initialize(id, hsh, subsection)
super super
@id = "property_number_of_bedrooms" @id = "property_number_of_bedrooms"
@depends_on = [{ "is_general_needs?" => true }] @depends_on = [{ "is_general_needs?" => true, "is_beds_inferred?" => false }]
end end
def questions def questions

5
app/models/form/lettings/questions/beds.rb

@ -9,8 +9,11 @@ class Form::Lettings::Questions::Beds < ::Form::Question
@check_answers_card_number = 0 @check_answers_card_number = 0
@max = 12 @max = 12
@min = 1 @min = 1
@hint_text = "If shared accommodation, enter the number of bedrooms occupied by this household. A bedsit has 1 bedroom."
@step = 1 @step = 1
@question_number = 22 @question_number = 22
end end
def hint_text
form.start_year_after_2024? ? "If shared accommodation, enter the number of bedrooms occupied by this household." : "If shared accommodation, enter the number of bedrooms occupied by this household. A bedsit has 1 bedroom."
end
end end

2
app/models/form/lettings/questions/nationality_all_group.rb

@ -6,7 +6,7 @@ class Form::Lettings::Questions::NationalityAllGroup < ::Form::Question
@header = "What is the nationality of the lead tenant?" @header = "What is the nationality of the lead tenant?"
@type = "radio" @type = "radio"
@check_answers_card_number = 1 @check_answers_card_number = 1
@hint_text = "The lead tenant is the person in the household who does the most paid work. If several people do the same paid work, the lead tenant is whoever is the oldest." @hint_text = "The lead tenant is the person in the household who does the most paid work. If several people do the same paid work, the lead tenant is whoever is the oldest. If the lead tenant is a dual national of the United Kingdom and another country, enter United Kingdom. If they are a dual national of two other countries, the tenant should decide which country to enter."
@answer_options = ANSWER_OPTIONS @answer_options = ANSWER_OPTIONS
@question_number = 36 @question_number = 36
@conditional_for = { "nationality_all" => [12] } @conditional_for = { "nationality_all" => [12] }

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

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

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

@ -1,16 +1,26 @@
class Form::Sales::Pages::AboutDepositWithoutDiscount < ::Form::Page class Form::Sales::Pages::AboutDepositWithoutDiscount < ::Form::Page
def initialize(id, hsh, subsection, ownershipsch:) def initialize(id, hsh, subsection, ownershipsch:, optional:)
super(id, hsh, subsection) super(id, hsh, subsection)
@header = "About the deposit" @header = "About the deposit"
@depends_on = [{ "is_type_discount?" => false, "ownershipsch" => 1 },
{ "ownershipsch" => 2 },
{ "ownershipsch" => 3, "mortgageused" => 1 }]
@ownershipsch = ownershipsch @ownershipsch = ownershipsch
@optional = optional
end end
def questions def questions
@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 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 end

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

@ -1,5 +1,5 @@
class Form::Sales::Questions::DepositAmount < ::Form::Question class Form::Sales::Questions::DepositAmount < ::Form::Question
def initialize(id, hsh, subsection, ownershipsch:) def initialize(id, hsh, subsection, ownershipsch:, optional:)
super(id, hsh, subsection) super(id, hsh, subsection)
@id = "deposit" @id = "deposit"
@check_answer_label = "Cash deposit" @check_answer_label = "Cash deposit"
@ -10,10 +10,10 @@ class Form::Sales::Questions::DepositAmount < ::Form::Question
@step = 1 @step = 1
@width = 5 @width = 5
@prefix = "£" @prefix = "£"
@hint_text = "Enter the total cash sum paid by the buyer towards the property that was not funded by the mortgage"
@derived = true @derived = true
@ownershipsch = ownershipsch @ownershipsch = ownershipsch
@question_number = question_number @question_number = question_number
@optional = optional
end end
def selected_answer_option_is_derived?(_log) def selected_answer_option_is_derived?(_log)
@ -30,4 +30,12 @@ class Form::Sales::Questions::DepositAmount < ::Form::Question
116 116
end end
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 end

9
app/models/form/sales/questions/nationality_all_group.rb

@ -10,6 +10,7 @@ class Form::Sales::Questions::NationalityAllGroup < ::Form::Question
@question_number = buyer_index == 1 ? 24 : 32 @question_number = buyer_index == 1 ? 24 : 32
@conditional_for = buyer_index == 1 ? { "nationality_all" => [12] } : { "nationality_all_buyer2" => [12] } @conditional_for = buyer_index == 1 ? { "nationality_all" => [12] } : { "nationality_all_buyer2" => [12] }
@hidden_in_check_answers = { "depends_on" => [{ id => 12 }] } @hidden_in_check_answers = { "depends_on" => [{ id => 12 }] }
@buyer_index = buyer_index
end end
ANSWER_OPTIONS = { ANSWER_OPTIONS = {
@ -17,4 +18,12 @@ class Form::Sales::Questions::NationalityAllGroup < ::Form::Question
"12" => { "value" => "Other" }, "12" => { "value" => "Other" },
"0" => { "value" => "Buyer prefers not to say" }, "0" => { "value" => "Buyer prefers not to say" },
}.freeze }.freeze
def hint_text
if @buyer_index == 1
"Buyer 1 is the person in the household who does the most paid work. If it’s a joint purchase and the buyers do the same amount of paid work, buyer 1 is whoever is the oldest. If buyer 1 is a dual national of the United Kingdom and another country, enter United Kingdom. If they are a dual national of two other countries, the buyer should decide which country to enter."
else
"If buyer 2 is a dual national of the United Kingdom and another country, enter United Kingdom. If they are a dual national of two other countries, the buyer should decide which country to enter."
end
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::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::ExtraBorrowing.new("extra_borrowing_discounted_ownership", nil, self, ownershipsch: 2),
Form::Sales::Pages::ExtraBorrowingValueCheck.new("extra_borrowing_value_check", nil, self), 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::ExtraBorrowingValueCheck.new("extra_borrowing_deposit_value_check", nil, self),
Form::Sales::Pages::DepositValueCheck.new("discounted_ownership_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), 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::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::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::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), Form::Sales::Pages::DepositValueCheck.new("outright_sale_deposit_value_check", nil, self),
leasehold_charge_pages, leasehold_charge_pages,
Form::Sales::Pages::MonthlyChargesValueCheck.new("monthly_charges_outright_sale_value_check", nil, self), 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::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::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::ExtraBorrowing.new("extra_borrowing_shared_ownership", nil, self, ownershipsch: 1),
Form::Sales::Pages::AboutDepositWithDiscount.new(nil, nil, self), Form::Sales::Pages::AboutDepositWithDiscount.new("about_deposit_with_discount", nil, self, optional: false),
Form::Sales::Pages::AboutDepositWithoutDiscount.new("about_deposit_shared_ownership", nil, self, ownershipsch: 1), (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::DepositValueCheck.new("deposit_value_check", nil, self),
Form::Sales::Pages::SharedOwnershipDepositValueCheck.new("shared_ownership_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::MonthlyRent.new(nil, nil, self),
Form::Sales::Pages::LeaseholdCharges.new("leasehold_charges_shared_ownership", nil, self, ownershipsch: 1), 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), Form::Sales::Pages::MonthlyChargesValueCheck.new("monthly_charges_shared_ownership_value_check", nil, self),
] ].compact
end end
def displayed_in_tasklist?(log) def displayed_in_tasklist?(log)

4
app/models/lettings_log.rb

@ -356,6 +356,10 @@ class LettingsLog < Log
unittype_gn == 2 unittype_gn == 2
end end
def is_beds_inferred?
form.start_year_after_2024? && is_bedsit?
end
def is_shared_housing? def is_shared_housing?
# 4: Shared flat or maisonette # 4: Shared flat or maisonette
# 9: Shared house # 9: Shared house

5
app/models/sales_log.rb

@ -121,6 +121,7 @@ class SalesLog < Log
not_required << "proplen" if proplen_optional? not_required << "proplen" if proplen_optional?
not_required << "mortlen" if mortlen_optional? not_required << "mortlen" if mortlen_optional?
not_required << "frombeds" if frombeds_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 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? def is_not_staircasing?
staircase == 2 || staircase == 3 staircase == 2 || staircase == 3
end end
def stairowned_100?
stairowned == 100
end
end end

2
app/models/validations/property_validations.rb

@ -34,7 +34,7 @@ module Validations::PropertyValidations
def validate_shared_housing_rooms(record) def validate_shared_housing_rooms(record)
unless record.unittype_gn.nil? unless record.unittype_gn.nil?
if record.is_bedsit? && record.beds != 1 && record.beds.present? if record.is_bedsit? && record.beds != 1 && record.beds.present? && !record.form.start_year_after_2024?
record.errors.add :unittype_gn, I18n.t("validations.property.unittype_gn.one_bedroom_bedsit") record.errors.add :unittype_gn, I18n.t("validations.property.unittype_gn.one_bedroom_bedsit")
record.errors.add :beds, I18n.t("validations.property.unittype_gn.one_bedroom_bedsit") record.errors.add :beds, I18n.t("validations.property.unittype_gn.one_bedroom_bedsit")
end end

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

@ -110,4 +110,14 @@ module Validations::Sales::SaleInformationValidations
end end
end 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 end

2
app/services/bulk_upload/lettings/year2024/row_parser.rb

@ -1036,7 +1036,7 @@ private
attributes["unittype_gn"] = field_26 attributes["unittype_gn"] = field_26
attributes["builtype"] = field_27 attributes["builtype"] = field_27
attributes["wchair"] = field_28 attributes["wchair"] = field_28
attributes["beds"] = field_29 attributes["beds"] = field_26 == 2 ? 1 : field_29
attributes["joint"] = field_36 attributes["joint"] = field_36
attributes["startertenancy"] = field_37 attributes["startertenancy"] = field_37
attributes["tenancy"] = field_38 attributes["tenancy"] = field_38

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

@ -341,6 +341,14 @@ class BulkUpload::Sales::Year2024::RowParser
}, },
on: :before_log 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, validates :field_9,
presence: { presence: {
message: I18n.t("validations.not_answered", question: "type of shared ownership sale"), message: I18n.t("validations.not_answered", question: "type of shared ownership sale"),

2
config/locales/en.yml

@ -624,6 +624,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_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." 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." 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: merge_request:
organisation_part_of_another_merge: "This organisation is part of another merge - select a different one" 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" organisation_not_selected: "Select an organisation from the search list"

33
spec/models/form/lettings/pages/property_number_of_bedrooms_spec.rb

@ -0,0 +1,33 @@
require "rails_helper"
RSpec.describe Form::Lettings::Pages::PropertyNumberOfBedrooms, 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[beds])
end
it "has the correct id" do
expect(page.id).to eq("property_number_of_bedrooms")
end
it "has the correct header" do
expect(page.header).to be_nil
end
it "has the correct description" do
expect(page.description).to be_nil
end
it "has the correct depends_on" do
expect(page.depends_on).to eq([{ "is_general_needs?" => true, "is_beds_inferred?" => false }])
end
end

65
spec/models/form/lettings/questions/beds_spec.rb

@ -0,0 +1,65 @@
require "rails_helper"
RSpec.describe Form::Lettings::Questions::Beds, 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) }
let(:subsection) { instance_double(Form::Subsection) }
let(:form) { instance_double(Form) }
before do
allow(form).to receive(:start_year_after_2024?).and_return(false)
allow(page).to receive(:subsection).and_return(subsection)
allow(subsection).to receive(:form).and_return(form)
end
it "has correct page" do
expect(question.page).to eq(page)
end
it "has the correct id" do
expect(question.id).to eq("beds")
end
it "has the correct header" do
expect(question.header).to eq("How many bedrooms does the property have?")
end
it "has the correct check_answer_label" do
expect(question.check_answer_label).to eq("Number of bedrooms")
end
it "has the correct type" do
expect(question.type).to eq("numeric")
end
it "is not marked as derived" do
expect(question.derived?).to be false
end
it "has the correct min" do
expect(question.min).to eq(1)
end
it "has the correct max" do
expect(question.max).to eq(12)
end
context "with 2023/24 form" do
it "has the correct hint_text" do
expect(question.hint_text).to eq("If shared accommodation, enter the number of bedrooms occupied by this household. A bedsit has 1 bedroom.")
end
end
context "with 2024/25 form" do
before do
allow(form).to receive(:start_year_after_2024?).and_return(true)
end
it "has the correct hint_text" do
expect(question.hint_text).to eq("If shared accommodation, enter the number of bedrooms occupied by this household.")
end
end
end

2
spec/models/form/lettings/questions/nationality_all_group_spec.rb

@ -26,7 +26,7 @@ RSpec.describe Form::Lettings::Questions::NationalityAllGroup, type: :model do
end end
it "has the correct hint_text" do it "has the correct hint_text" do
expect(question.hint_text).to eq("The lead tenant is the person in the household who does the most paid work. If several people do the same paid work, the lead tenant is whoever is the oldest.") expect(question.hint_text).to eq("The lead tenant is the person in the household who does the most paid work. If several people do the same paid work, the lead tenant is whoever is the oldest. If the lead tenant is a dual national of the United Kingdom and another country, enter United Kingdom. If they are a dual national of two other countries, the tenant should decide which country to enter.")
end end
it "has the correct answer_options" do it "has the correct answer_options" do

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

@ -1,12 +1,16 @@
require "rails_helper" require "rails_helper"
RSpec.describe Form::Sales::Pages::AboutDepositWithDiscount, type: :model do 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(:page_definition) { nil }
let(:subsection) { instance_double(Form::Subsection) } 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 it "has correct subsection" do
expect(page.subsection).to eq(subsection) expect(page.subsection).to eq(subsection)
end end
@ -32,4 +36,36 @@ RSpec.describe Form::Sales::Pages::AboutDepositWithDiscount, type: :model do
[{ "is_type_discount?" => true }], [{ "is_type_discount?" => true }],
) )
end 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 end

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

@ -1,12 +1,16 @@
require "rails_helper" require "rails_helper"
RSpec.describe Form::Sales::Pages::AboutDepositWithoutDiscount, type: :model do 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_id) { nil }
let(:page_definition) { nil } let(:page_definition) { nil }
let(:subsection) { instance_double(Form::Subsection) } 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 it "has correct subsection" do
expect(page.subsection).to eq(subsection) expect(page.subsection).to eq(subsection)
end end
@ -34,4 +38,42 @@ RSpec.describe Form::Sales::Pages::AboutDepositWithoutDiscount, type: :model do
{ "ownershipsch" => 3, "mortgageused" => 1 }], { "ownershipsch" => 3, "mortgageused" => 1 }],
) )
end 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 end

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

@ -1,7 +1,7 @@
require "rails_helper" require "rails_helper"
RSpec.describe Form::Sales::Questions::DepositAmount, type: :model do 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_id) { nil }
let(:question_definition) { nil } let(:question_definition) { nil }
@ -50,4 +50,12 @@ RSpec.describe Form::Sales::Questions::DepositAmount, type: :model do
it "has correct max" do it "has correct max" do
expect(question.max).to eq(999_999) expect(question.max).to eq(999_999)
end 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 end

4
spec/models/form/sales/questions/nationality_all_group_spec.rb

@ -47,7 +47,7 @@ RSpec.describe Form::Sales::Questions::NationalityAllGroup, type: :model do
end end
it "has the correct hint" do it "has the correct hint" do
expect(question.hint_text).to eq "Buyer 1 is the person in the household who does the most paid work. If it’s a joint purchase and the buyers do the same amount of paid work, buyer 1 is whoever is the oldest." expect(question.hint_text).to eq "Buyer 1 is the person in the household who does the most paid work. If it’s a joint purchase and the buyers do the same amount of paid work, buyer 1 is whoever is the oldest. If buyer 1 is a dual national of the United Kingdom and another country, enter United Kingdom. If they are a dual national of two other countries, the buyer should decide which country to enter."
end end
it "has the correct header" do it "has the correct header" do
@ -75,7 +75,7 @@ RSpec.describe Form::Sales::Questions::NationalityAllGroup, type: :model do
end end
it "has the correct hint" do it "has the correct hint" do
expect(question.hint_text).to eq("") expect(question.hint_text).to eq "If buyer 2 is a dual national of the United Kingdom and another country, enter United Kingdom. If they are a dual national of two other countries, the buyer should decide which country to enter."
end end
it "has the correct header" do it "has the correct header" do

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(:subsection_definition) { nil }
let(:section) { instance_double(Form::Sales::Sections::SaleInformation) } 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 it "has correct section" do
expect(shared_ownership_scheme.section).to eq(section) expect(shared_ownership_scheme.section).to eq(section)
end end

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

@ -756,4 +756,48 @@ RSpec.describe Validations::Sales::SaleInformationValidations do
end end
end 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 end

18
spec/services/bulk_upload/lettings/year2024/row_parser_spec.rb

@ -1816,6 +1816,24 @@ RSpec.describe BulkUpload::Lettings::Year2024::RowParser do
end end
end end
describe "#beds" do
context "when property is a bedsit" do
let(:attributes) { setup_section_params.merge({ field_26: 2, field_29: 2 }) }
it "sets value to 1 even if field_29 contradicts this" do
expect(parser.log.beds).to be(1)
end
end
context "when property is not a bedsit" do
let(:attributes) { setup_section_params.merge({ field_26: 1, field_29: 2 }) }
it "sets value to field_29" do
expect(parser.log.beds).to be(2)
end
end
end
describe "#cbl" do describe "#cbl" do
context "when field_112 is yes ie 1" do context "when field_112 is yes ie 1" do
let(:attributes) { { bulk_upload:, field_112: 1 } } let(:attributes) { { bulk_upload:, field_112: 1 } }

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

@ -975,6 +975,36 @@ RSpec.describe BulkUpload::Sales::Year2024::RowParser do
end end
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 describe "soft validations" do
context "when soft validation is triggered" do context "when soft validation is triggered" do
let(:attributes) { valid_attributes.merge({ field_31: 22, field_35: 5 }) } let(:attributes) { valid_attributes.merge({ field_31: 22, field_35: 5 }) }

Loading…
Cancel
Save