From 39b6c4ddd8fc61d80e9a392e662f3355c8a308eb Mon Sep 17 00:00:00 2001 From: natdeanlewissoftwire <94526761+natdeanlewissoftwire@users.noreply.github.com> Date: Mon, 12 Feb 2024 12:31:12 +0000 Subject: [PATCH 1/4] CLDC-3135 Infer beds for 24/25 bedsits (#2167) * feat: for 24/25 onwards, infer beds = 1 for bedsits, change hint text and remove validation * feat: add tests * feat: update bulk upload inferral * feat: update tests * refactor: rename file * refactor: nest 2024 changes for future DRYness * refactor: lint --- .../lettings_log_variables.rb | 6 ++ .../pages/property_number_of_bedrooms.rb | 2 +- app/models/form/lettings/questions/beds.rb | 5 +- app/models/lettings_log.rb | 4 ++ .../validations/property_validations.rb | 2 +- .../lettings/year2024/row_parser.rb | 2 +- .../pages/property_number_of_bedrooms_spec.rb | 33 ++++++++++ .../form/lettings/questions/beds_spec.rb | 65 +++++++++++++++++++ .../lettings/year2024/row_parser_spec.rb | 18 +++++ 9 files changed, 133 insertions(+), 4 deletions(-) create mode 100644 spec/models/form/lettings/pages/property_number_of_bedrooms_spec.rb create mode 100644 spec/models/form/lettings/questions/beds_spec.rb diff --git a/app/models/derived_variables/lettings_log_variables.rb b/app/models/derived_variables/lettings_log_variables.rb index d0aab14cb..ac17e0219 100644 --- a/app/models/derived_variables/lettings_log_variables.rb +++ b/app/models/derived_variables/lettings_log_variables.rb @@ -91,6 +91,9 @@ module DerivedVariables::LettingsLogVariables self.prevten = 30 if owning_organisation&.provider_type == "LA" end end + if form.start_year_after_2024? && is_bedsit? + self.beds = 1 + end child_under_16_constraints! @@ -179,6 +182,9 @@ private self.wchair = nil self.location_id = nil end + if form.start_year_after_2024? && (unittype_gn_changed? && unittype_gn_was == 2) + self.beds = nil + end end def get_totelder diff --git a/app/models/form/lettings/pages/property_number_of_bedrooms.rb b/app/models/form/lettings/pages/property_number_of_bedrooms.rb index c3a1a2365..8ed9dc37a 100644 --- a/app/models/form/lettings/pages/property_number_of_bedrooms.rb +++ b/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) super @id = "property_number_of_bedrooms" - @depends_on = [{ "is_general_needs?" => true }] + @depends_on = [{ "is_general_needs?" => true, "is_beds_inferred?" => false }] end def questions diff --git a/app/models/form/lettings/questions/beds.rb b/app/models/form/lettings/questions/beds.rb index 6fa6c7c2b..e75e688bb 100644 --- a/app/models/form/lettings/questions/beds.rb +++ b/app/models/form/lettings/questions/beds.rb @@ -9,8 +9,11 @@ class Form::Lettings::Questions::Beds < ::Form::Question @check_answers_card_number = 0 @max = 12 @min = 1 - @hint_text = "If shared accommodation, enter the number of bedrooms occupied by this household. A bedsit has 1 bedroom." @step = 1 @question_number = 22 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 diff --git a/app/models/lettings_log.rb b/app/models/lettings_log.rb index 03405a12d..cc8c7d58b 100644 --- a/app/models/lettings_log.rb +++ b/app/models/lettings_log.rb @@ -356,6 +356,10 @@ class LettingsLog < Log unittype_gn == 2 end + def is_beds_inferred? + form.start_year_after_2024? && is_bedsit? + end + def is_shared_housing? # 4: Shared flat or maisonette # 9: Shared house diff --git a/app/models/validations/property_validations.rb b/app/models/validations/property_validations.rb index 2f2d8d6b8..ba8318282 100644 --- a/app/models/validations/property_validations.rb +++ b/app/models/validations/property_validations.rb @@ -34,7 +34,7 @@ module Validations::PropertyValidations def validate_shared_housing_rooms(record) 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 :beds, I18n.t("validations.property.unittype_gn.one_bedroom_bedsit") end diff --git a/app/services/bulk_upload/lettings/year2024/row_parser.rb b/app/services/bulk_upload/lettings/year2024/row_parser.rb index c87cd0c03..5f05b6e10 100644 --- a/app/services/bulk_upload/lettings/year2024/row_parser.rb +++ b/app/services/bulk_upload/lettings/year2024/row_parser.rb @@ -1036,7 +1036,7 @@ private attributes["unittype_gn"] = field_26 attributes["builtype"] = field_27 attributes["wchair"] = field_28 - attributes["beds"] = field_29 + attributes["beds"] = field_26 == 2 ? 1 : field_29 attributes["joint"] = field_36 attributes["startertenancy"] = field_37 attributes["tenancy"] = field_38 diff --git a/spec/models/form/lettings/pages/property_number_of_bedrooms_spec.rb b/spec/models/form/lettings/pages/property_number_of_bedrooms_spec.rb new file mode 100644 index 000000000..f6cec39e8 --- /dev/null +++ b/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 diff --git a/spec/models/form/lettings/questions/beds_spec.rb b/spec/models/form/lettings/questions/beds_spec.rb new file mode 100644 index 000000000..77340f5d5 --- /dev/null +++ b/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 diff --git a/spec/services/bulk_upload/lettings/year2024/row_parser_spec.rb b/spec/services/bulk_upload/lettings/year2024/row_parser_spec.rb index a37110785..58be059fc 100644 --- a/spec/services/bulk_upload/lettings/year2024/row_parser_spec.rb +++ b/spec/services/bulk_upload/lettings/year2024/row_parser_spec.rb @@ -1816,6 +1816,24 @@ RSpec.describe BulkUpload::Lettings::Year2024::RowParser do 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 context "when field_112 is yes ie 1" do let(:attributes) { { bulk_upload:, field_112: 1 } } From ea1a7b7f547aef1a9bfb769b419590af807f8b2b Mon Sep 17 00:00:00 2001 From: kosiakkatrina <54268893+kosiakkatrina@users.noreply.github.com> Date: Mon, 12 Feb 2024 15:06:58 +0000 Subject: [PATCH 2/4] 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 --- .../pages/about_deposit_with_discount.rb | 17 ++++--- .../pages/about_deposit_without_discount.rb | 20 ++++++--- .../form/sales/questions/deposit_amount.rb | 12 ++++- .../discounted_ownership_scheme.rb | 2 +- .../form/sales/subsections/outright_sale.rb | 2 +- .../subsections/shared_ownership_scheme.rb | 8 ++-- app/models/sales_log.rb | 5 +++ .../sales/sale_information_validations.rb | 10 +++++ .../bulk_upload/sales/year2024/row_parser.rb | 8 ++++ config/locales/en.yml | 2 + .../pages/about_deposit_with_discount_spec.rb | 40 ++++++++++++++++- .../about_deposit_without_discount_spec.rb | 44 ++++++++++++++++++- .../sales/questions/deposit_amount_spec.rb | 10 ++++- .../shared_ownership_scheme_spec.rb | 4 ++ .../sale_information_validations_spec.rb | 44 +++++++++++++++++++ .../sales/year2024/row_parser_spec.rb | 30 +++++++++++++ 16 files changed, 237 insertions(+), 21 deletions(-) diff --git a/app/models/form/sales/pages/about_deposit_with_discount.rb b/app/models/form/sales/pages/about_deposit_with_discount.rb index 1c684b0bc..5d1e41a95 100644 --- a/app/models/form/sales/pages/about_deposit_with_discount.rb +++ b/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 diff --git a/app/models/form/sales/pages/about_deposit_without_discount.rb b/app/models/form/sales/pages/about_deposit_without_discount.rb index 1114b8f84..fdd74cf31 100644 --- a/app/models/form/sales/pages/about_deposit_without_discount.rb +++ b/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 diff --git a/app/models/form/sales/questions/deposit_amount.rb b/app/models/form/sales/questions/deposit_amount.rb index 784bb56a1..689299e56 100644 --- a/app/models/form/sales/questions/deposit_amount.rb +++ b/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 diff --git a/app/models/form/sales/subsections/discounted_ownership_scheme.rb b/app/models/form/sales/subsections/discounted_ownership_scheme.rb index 52ee9e95c..200565ab6 100644 --- a/app/models/form/sales/subsections/discounted_ownership_scheme.rb +++ b/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), diff --git a/app/models/form/sales/subsections/outright_sale.rb b/app/models/form/sales/subsections/outright_sale.rb index 245cbcb10..39275d7b2 100644 --- a/app/models/form/sales/subsections/outright_sale.rb +++ b/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), diff --git a/app/models/form/sales/subsections/shared_ownership_scheme.rb b/app/models/form/sales/subsections/shared_ownership_scheme.rb index 66a711dcd..51abe3656 100644 --- a/app/models/form/sales/subsections/shared_ownership_scheme.rb +++ b/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) diff --git a/app/models/sales_log.rb b/app/models/sales_log.rb index 76c43b09e..13d16a786 100644 --- a/app/models/sales_log.rb +++ b/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 diff --git a/app/models/validations/sales/sale_information_validations.rb b/app/models/validations/sales/sale_information_validations.rb index 0aaa77a93..c8a4e46dc 100644 --- a/app/models/validations/sales/sale_information_validations.rb +++ b/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 diff --git a/app/services/bulk_upload/sales/year2024/row_parser.rb b/app/services/bulk_upload/sales/year2024/row_parser.rb index 28e7ef100..c7a5349d0 100644 --- a/app/services/bulk_upload/sales/year2024/row_parser.rb +++ b/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"), diff --git a/config/locales/en.yml b/config/locales/en.yml index 204a20b4e..37239d234 100644 --- a/config/locales/en.yml +++ b/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" diff --git a/spec/models/form/sales/pages/about_deposit_with_discount_spec.rb b/spec/models/form/sales/pages/about_deposit_with_discount_spec.rb index cc33a9641..89db397f1 100644 --- a/spec/models/form/sales/pages/about_deposit_with_discount_spec.rb +++ b/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 diff --git a/spec/models/form/sales/pages/about_deposit_without_discount_spec.rb b/spec/models/form/sales/pages/about_deposit_without_discount_spec.rb index 1a0b5ef4d..1a4e420c6 100644 --- a/spec/models/form/sales/pages/about_deposit_without_discount_spec.rb +++ b/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 diff --git a/spec/models/form/sales/questions/deposit_amount_spec.rb b/spec/models/form/sales/questions/deposit_amount_spec.rb index e0a77b7fc..80429b5af 100644 --- a/spec/models/form/sales/questions/deposit_amount_spec.rb +++ b/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 diff --git a/spec/models/form/sales/subsections/shared_ownership_scheme_spec.rb b/spec/models/form/sales/subsections/shared_ownership_scheme_spec.rb index 192f7cbda..3746768d0 100644 --- a/spec/models/form/sales/subsections/shared_ownership_scheme_spec.rb +++ b/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 diff --git a/spec/models/validations/sales/sale_information_validations_spec.rb b/spec/models/validations/sales/sale_information_validations_spec.rb index 73243e9fa..3d323112e 100644 --- a/spec/models/validations/sales/sale_information_validations_spec.rb +++ b/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 diff --git a/spec/services/bulk_upload/sales/year2024/row_parser_spec.rb b/spec/services/bulk_upload/sales/year2024/row_parser_spec.rb index 93e6fdca1..d93453a22 100644 --- a/spec/services/bulk_upload/sales/year2024/row_parser_spec.rb +++ b/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 }) } From cc8ba09b92a43c245dd2e686b254c24563078eab Mon Sep 17 00:00:00 2001 From: kosiakkatrina <54268893+kosiakkatrina@users.noreply.github.com> Date: Mon, 12 Feb 2024 15:13:19 +0000 Subject: [PATCH 3/4] Update nationality hint text (#2225) --- .../form/lettings/questions/nationality_all_group.rb | 2 +- app/models/form/sales/questions/nationality_all_group.rb | 9 +++++++++ .../lettings/questions/nationality_all_group_spec.rb | 2 +- .../form/sales/questions/nationality_all_group_spec.rb | 4 ++-- 4 files changed, 13 insertions(+), 4 deletions(-) diff --git a/app/models/form/lettings/questions/nationality_all_group.rb b/app/models/form/lettings/questions/nationality_all_group.rb index 2ba9e5cde..49b000a16 100644 --- a/app/models/form/lettings/questions/nationality_all_group.rb +++ b/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?" @type = "radio" @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 @question_number = 36 @conditional_for = { "nationality_all" => [12] } diff --git a/app/models/form/sales/questions/nationality_all_group.rb b/app/models/form/sales/questions/nationality_all_group.rb index c9b1e71bc..faf29487e 100644 --- a/app/models/form/sales/questions/nationality_all_group.rb +++ b/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 @conditional_for = buyer_index == 1 ? { "nationality_all" => [12] } : { "nationality_all_buyer2" => [12] } @hidden_in_check_answers = { "depends_on" => [{ id => 12 }] } + @buyer_index = buyer_index end ANSWER_OPTIONS = { @@ -17,4 +18,12 @@ class Form::Sales::Questions::NationalityAllGroup < ::Form::Question "12" => { "value" => "Other" }, "0" => { "value" => "Buyer prefers not to say" }, }.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 diff --git a/spec/models/form/lettings/questions/nationality_all_group_spec.rb b/spec/models/form/lettings/questions/nationality_all_group_spec.rb index ff8a47b59..d92551546 100644 --- a/spec/models/form/lettings/questions/nationality_all_group_spec.rb +++ b/spec/models/form/lettings/questions/nationality_all_group_spec.rb @@ -26,7 +26,7 @@ RSpec.describe Form::Lettings::Questions::NationalityAllGroup, type: :model do end 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 it "has the correct answer_options" do diff --git a/spec/models/form/sales/questions/nationality_all_group_spec.rb b/spec/models/form/sales/questions/nationality_all_group_spec.rb index b0bfbbfc8..cd70b2a12 100644 --- a/spec/models/form/sales/questions/nationality_all_group_spec.rb +++ b/spec/models/form/sales/questions/nationality_all_group_spec.rb @@ -47,7 +47,7 @@ RSpec.describe Form::Sales::Questions::NationalityAllGroup, type: :model do end 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 it "has the correct header" do @@ -75,7 +75,7 @@ RSpec.describe Form::Sales::Questions::NationalityAllGroup, type: :model do end 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 it "has the correct header" do From b4c96508e1bd813aa79e2be239291a2c65ee21c0 Mon Sep 17 00:00:00 2001 From: kosiakkatrina <54268893+kosiakkatrina@users.noreply.github.com> Date: Mon, 12 Feb 2024 16:58:36 +0000 Subject: [PATCH 4/4] Update postgres in dockerfile (#2234) --- Dockerfile | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Dockerfile b/Dockerfile index da6d4ba6f..a65696f84 100644 --- a/Dockerfile +++ b/Dockerfile @@ -10,7 +10,7 @@ RUN apk add --update --no-cache tzdata && \ # build-base: compilation tools for bundle # yarn: node package manager # 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 RUN gem install bundler:2.3.14 --no-document