From 3d360d78a88fbd48e8c0eb84d007beefc38bc2c2 Mon Sep 17 00:00:00 2001 From: kosiakkatrina <54268893+kosiakkatrina@users.noreply.github.com> Date: Tue, 17 Jan 2023 09:28:01 +0000 Subject: [PATCH 1/5] CLDC-1543 Route to mortgage questions only if mortgage is used (#1179) * Route to mortagage questions only if mortgage is used * Fix tests for deposit derived var * more routing * Only display mortgage lender questions if mortgage is used --- .../form/sales/pages/about_deposit_without_discount.rb | 4 +++- app/models/form/sales/pages/mortgage_lender.rb | 3 +++ app/models/form/sales/pages/mortgage_length.rb | 7 +++++++ app/models/form/sales/questions/deposit_amount.rb | 5 +++++ .../sales/pages/about_deposit_without_discount_spec.rb | 4 +++- spec/models/form/sales/pages/mortgage_lender_spec.rb | 4 +++- spec/models/form/sales/pages/mortgage_length_spec.rb | 4 +++- spec/models/form/sales/questions/deposit_amount_spec.rb | 4 ++-- 8 files changed, 29 insertions(+), 6 deletions(-) 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 65a59e6c0..e8e387eba 100644 --- a/app/models/form/sales/pages/about_deposit_without_discount.rb +++ b/app/models/form/sales/pages/about_deposit_without_discount.rb @@ -2,7 +2,9 @@ class Form::Sales::Pages::AboutDepositWithoutDiscount < ::Form::Page def initialize(id, hsh, subsection) super @header = "About the deposit" - @depends_on = [{ "is_type_discount?" => false }] + @depends_on = [{ "is_type_discount?" => false, "ownershipsch" => 1 }, + { "ownershipsch" => 2 }, + { "ownershipsch" => 3, "mortgageused" => 1 }] end def questions diff --git a/app/models/form/sales/pages/mortgage_lender.rb b/app/models/form/sales/pages/mortgage_lender.rb index 96ebd0733..552d7abf8 100644 --- a/app/models/form/sales/pages/mortgage_lender.rb +++ b/app/models/form/sales/pages/mortgage_lender.rb @@ -4,6 +4,9 @@ class Form::Sales::Pages::MortgageLender < ::Form::Page @header = "" @description = "" @subsection = subsection + @depends_on = [{ + "mortgageused" => 1, + }] end def questions diff --git a/app/models/form/sales/pages/mortgage_length.rb b/app/models/form/sales/pages/mortgage_length.rb index 2877cffd8..979369bdd 100644 --- a/app/models/form/sales/pages/mortgage_length.rb +++ b/app/models/form/sales/pages/mortgage_length.rb @@ -1,4 +1,11 @@ class Form::Sales::Pages::MortgageLength < ::Form::Page + def initialize(id, hsh, subsection) + super + @depends_on = [{ + "mortgageused" => 1, + }] + end + def questions @questions ||= [ Form::Sales::Questions::MortgageLength.new(nil, nil, self), diff --git a/app/models/form/sales/questions/deposit_amount.rb b/app/models/form/sales/questions/deposit_amount.rb index b054f76f2..094f47697 100644 --- a/app/models/form/sales/questions/deposit_amount.rb +++ b/app/models/form/sales/questions/deposit_amount.rb @@ -9,5 +9,10 @@ class Form::Sales::Questions::DepositAmount < ::Form::Question @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 + end + + def selected_answer_option_is_derived?(_log) + true 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 8d5bd84f2..62212e011 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 @@ -29,7 +29,9 @@ RSpec.describe Form::Sales::Pages::AboutDepositWithoutDiscount, type: :model do it "has correct depends_on" do expect(page.depends_on).to eq( - [{ "is_type_discount?" => false }], + [{ "is_type_discount?" => false, "ownershipsch" => 1 }, + { "ownershipsch" => 2 }, + { "ownershipsch" => 3, "mortgageused" => 1 }], ) end end diff --git a/spec/models/form/sales/pages/mortgage_lender_spec.rb b/spec/models/form/sales/pages/mortgage_lender_spec.rb index 430e7ea1c..fafa8e043 100644 --- a/spec/models/form/sales/pages/mortgage_lender_spec.rb +++ b/spec/models/form/sales/pages/mortgage_lender_spec.rb @@ -28,6 +28,8 @@ RSpec.describe Form::Sales::Pages::MortgageLender, type: :model do end it "has correct depends_on" do - expect(page.depends_on).to be_nil + expect(page.depends_on).to eq([{ + "mortgageused" => 1, + }]) end end diff --git a/spec/models/form/sales/pages/mortgage_length_spec.rb b/spec/models/form/sales/pages/mortgage_length_spec.rb index bc63bc178..ef2573e57 100644 --- a/spec/models/form/sales/pages/mortgage_length_spec.rb +++ b/spec/models/form/sales/pages/mortgage_length_spec.rb @@ -28,6 +28,8 @@ RSpec.describe Form::Sales::Pages::MortgageLength, type: :model do end it "has correct depends_on" do - expect(page.depends_on).to be_nil + expect(page.depends_on).to eq([{ + "mortgageused" => 1, + }]) 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 9eaa628cf..db47387d3 100644 --- a/spec/models/form/sales/questions/deposit_amount_spec.rb +++ b/spec/models/form/sales/questions/deposit_amount_spec.rb @@ -27,8 +27,8 @@ RSpec.describe Form::Sales::Questions::DepositAmount, type: :model do expect(question.type).to eq("numeric") end - it "is not marked as derived" do - expect(question.derived?).to be false + it "is marked as derived" do + expect(question.derived?).to be true end it "has the correct hint" do From 93e444e3f8ad018066a5d114c1a38cca3fe8e093 Mon Sep 17 00:00:00 2001 From: kosiakkatrina <54268893+kosiakkatrina@users.noreply.github.com> Date: Tue, 17 Jan 2023 10:01:54 +0000 Subject: [PATCH 2/5] CLDC-1842 Display correct price questions for discounted ownership sales (#1175) * Do not display the grants question if the discounted sale type is rent to buy * Formatting and test --- app/models/form/sales/pages/about_price_not_rtb.rb | 1 + app/models/form/sales/pages/purchase_price.rb | 5 ++++- .../form/sales/subsections/discounted_ownership_scheme.rb | 1 + app/models/form/sales/subsections/outright_sale.rb | 2 +- app/models/sales_log.rb | 4 ++++ spec/models/form/sales/pages/about_price_not_rtb_spec.rb | 1 + spec/models/form/sales/pages/purchase_price_spec.rb | 7 +++++-- .../sales/subsections/discounted_ownership_scheme_spec.rb | 1 + spec/models/form/sales/subsections/outright_sale_spec.rb | 2 +- spec/models/form_handler_spec.rb | 4 ++-- 10 files changed, 21 insertions(+), 7 deletions(-) diff --git a/app/models/form/sales/pages/about_price_not_rtb.rb b/app/models/form/sales/pages/about_price_not_rtb.rb index 6e1011a28..ce55d6cd8 100644 --- a/app/models/form/sales/pages/about_price_not_rtb.rb +++ b/app/models/form/sales/pages/about_price_not_rtb.rb @@ -5,6 +5,7 @@ class Form::Sales::Pages::AboutPriceNotRtb < ::Form::Page @header = "About the price of the property" @depends_on = [{ "right_to_buy?" => false, + "rent_to_buy_full_ownership?" => false, }] end diff --git a/app/models/form/sales/pages/purchase_price.rb b/app/models/form/sales/pages/purchase_price.rb index 22277dc5a..dc9f7576e 100644 --- a/app/models/form/sales/pages/purchase_price.rb +++ b/app/models/form/sales/pages/purchase_price.rb @@ -1,7 +1,10 @@ class Form::Sales::Pages::PurchasePrice < ::Form::Page def initialize(id, hsh, subsection) super - @id = "purchase_price" + @depends_on = [ + { "ownershipsch" => 3 }, + { "rent_to_buy_full_ownership?" => true }, + ] end def questions diff --git a/app/models/form/sales/subsections/discounted_ownership_scheme.rb b/app/models/form/sales/subsections/discounted_ownership_scheme.rb index 62b5bd9a5..88456094f 100644 --- a/app/models/form/sales/subsections/discounted_ownership_scheme.rb +++ b/app/models/form/sales/subsections/discounted_ownership_scheme.rb @@ -11,6 +11,7 @@ class Form::Sales::Subsections::DiscountedOwnershipScheme < ::Form::Subsection Form::Sales::Pages::LivingBeforePurchase.new("living_before_purchase_discounted_ownership", nil, self), Form::Sales::Pages::AboutPriceRtb.new(nil, nil, self), Form::Sales::Pages::AboutPriceNotRtb.new(nil, nil, self), + Form::Sales::Pages::PurchasePrice.new("purchase_price_discounted_ownership", nil, self), Form::Sales::Pages::Mortgageused.new("mortgage_used_discounted_ownership", nil, self), Form::Sales::Pages::MortgageAmount.new("mortgage_amount_discounted_ownership", nil, self), Form::Sales::Pages::MortgageLender.new("mortgage_lender_discounted_ownership", nil, self), diff --git a/app/models/form/sales/subsections/outright_sale.rb b/app/models/form/sales/subsections/outright_sale.rb index 3429411a5..4f73e5977 100644 --- a/app/models/form/sales/subsections/outright_sale.rb +++ b/app/models/form/sales/subsections/outright_sale.rb @@ -8,7 +8,7 @@ class Form::Sales::Subsections::OutrightSale < ::Form::Subsection def pages @pages ||= [ - Form::Sales::Pages::PurchasePrice.new(nil, nil, self), + Form::Sales::Pages::PurchasePrice.new("purchase_price_outright_sale", nil, self), Form::Sales::Pages::Mortgageused.new("mortgage_used_outright_sale", nil, self), Form::Sales::Pages::MortgageAmount.new("mortgage_amount_outright_sale", nil, self), Form::Sales::Pages::MortgageLender.new("mortgage_lender_outright_sale", nil, self), diff --git a/app/models/sales_log.rb b/app/models/sales_log.rb index c5c51578b..df76ffcbf 100644 --- a/app/models/sales_log.rb +++ b/app/models/sales_log.rb @@ -121,6 +121,10 @@ class SalesLog < Log [9, 14, 27].include?(type) end + def rent_to_buy_full_ownership? + type == 29 + end + def is_type_discount? type == 18 end diff --git a/spec/models/form/sales/pages/about_price_not_rtb_spec.rb b/spec/models/form/sales/pages/about_price_not_rtb_spec.rb index 07d168368..d6fc6c9ea 100644 --- a/spec/models/form/sales/pages/about_price_not_rtb_spec.rb +++ b/spec/models/form/sales/pages/about_price_not_rtb_spec.rb @@ -30,6 +30,7 @@ RSpec.describe Form::Sales::Pages::AboutPriceNotRtb, type: :model do it "has correct depends_on" do expect(page.depends_on).to eq([{ "right_to_buy?" => false, + "rent_to_buy_full_ownership?" => false, }]) end end diff --git a/spec/models/form/sales/pages/purchase_price_spec.rb b/spec/models/form/sales/pages/purchase_price_spec.rb index ab4cb6789..4d0be701f 100644 --- a/spec/models/form/sales/pages/purchase_price_spec.rb +++ b/spec/models/form/sales/pages/purchase_price_spec.rb @@ -3,7 +3,7 @@ require "rails_helper" RSpec.describe Form::Sales::Pages::PurchasePrice, type: :model do subject(:page) { described_class.new(page_id, page_definition, subsection) } - let(:page_id) { nil } + let(:page_id) { "purchase_price" } let(:page_definition) { nil } let(:subsection) { instance_double(Form::Subsection) } @@ -28,6 +28,9 @@ RSpec.describe Form::Sales::Pages::PurchasePrice, type: :model do end it "has correct depends_on" do - expect(page.depends_on).to be_nil + expect(page.depends_on).to eq([ + { "ownershipsch" => 3 }, + { "rent_to_buy_full_ownership?" => true }, + ]) end end diff --git a/spec/models/form/sales/subsections/discounted_ownership_scheme_spec.rb b/spec/models/form/sales/subsections/discounted_ownership_scheme_spec.rb index 221c8e4f3..1ecc1f9cf 100644 --- a/spec/models/form/sales/subsections/discounted_ownership_scheme_spec.rb +++ b/spec/models/form/sales/subsections/discounted_ownership_scheme_spec.rb @@ -17,6 +17,7 @@ RSpec.describe Form::Sales::Subsections::DiscountedOwnershipScheme, type: :model living_before_purchase_discounted_ownership about_price_rtb about_price_not_rtb + purchase_price_discounted_ownership mortgage_used_discounted_ownership mortgage_amount_discounted_ownership mortgage_lender_discounted_ownership diff --git a/spec/models/form/sales/subsections/outright_sale_spec.rb b/spec/models/form/sales/subsections/outright_sale_spec.rb index b1617a85b..fa31bc843 100644 --- a/spec/models/form/sales/subsections/outright_sale_spec.rb +++ b/spec/models/form/sales/subsections/outright_sale_spec.rb @@ -14,7 +14,7 @@ RSpec.describe Form::Sales::Subsections::OutrightSale, type: :model do it "has correct pages" do expect(outright_sale.pages.map(&:id)).to eq( %w[ - purchase_price + purchase_price_outright_sale mortgage_used_outright_sale mortgage_amount_outright_sale mortgage_lender_outright_sale diff --git a/spec/models/form_handler_spec.rb b/spec/models/form_handler_spec.rb index 404a464cc..c9b7eeca0 100644 --- a/spec/models/form_handler_spec.rb +++ b/spec/models/form_handler_spec.rb @@ -52,14 +52,14 @@ RSpec.describe FormHandler do it "is able to load a current sales form" do form = form_handler.get_form("current_sales") expect(form).to be_a(Form) - expect(form.pages.count).to eq(144) + expect(form.pages.count).to eq(145) expect(form.name).to eq("2022_2023_sales") end it "is able to load a previous sales form" do form = form_handler.get_form("previous_sales") expect(form).to be_a(Form) - expect(form.pages.count).to eq(144) + expect(form.pages.count).to eq(145) expect(form.name).to eq("2021_2022_sales") end end From 24b8232874fc1d8e796fa4aab00170c52235b42b Mon Sep 17 00:00:00 2001 From: Phil Lee Date: Tue, 17 Jan 2023 10:56:49 +0000 Subject: [PATCH 3/5] order bulk upload errors by cell (#1193) --- .../bulk_upload_error_row_component.rb | 8 +++++++- .../bulk_upload_error_row_component_spec.rb | 16 ++++++++++++++++ 2 files changed, 23 insertions(+), 1 deletion(-) diff --git a/app/components/bulk_upload_error_row_component.rb b/app/components/bulk_upload_error_row_component.rb index de33fbb3a..e19717954 100644 --- a/app/components/bulk_upload_error_row_component.rb +++ b/app/components/bulk_upload_error_row_component.rb @@ -2,7 +2,7 @@ class BulkUploadErrorRowComponent < ViewComponent::Base attr_reader :bulk_upload_errors def initialize(bulk_upload_errors:) - @bulk_upload_errors = bulk_upload_errors + @bulk_upload_errors = sorted_errors(bulk_upload_errors) super end @@ -45,4 +45,10 @@ class BulkUploadErrorRowComponent < ViewComponent::Base def sales? bulk_upload.log_type == "sales" end + +private + + def sorted_errors(errors) + errors.sort_by { |e| e.cell.rjust(3, "0") } + end end diff --git a/spec/components/bulk_upload_error_row_component_spec.rb b/spec/components/bulk_upload_error_row_component_spec.rb index 86222acf4..4950817f0 100644 --- a/spec/components/bulk_upload_error_row_component_spec.rb +++ b/spec/components/bulk_upload_error_row_component_spec.rb @@ -49,6 +49,22 @@ RSpec.describe BulkUploadErrorRowComponent, type: :component do expect(result).to have_content(expected) end + context "when multiple errors for a row" do + subject(:component) { described_class.new(bulk_upload_errors:) } + + let(:bulk_upload_errors) do + [ + build(:bulk_upload_error, cell: "Z1"), + build(:bulk_upload_error, cell: "AB1"), + build(:bulk_upload_error, cell: "A1"), + ] + end + + it "is sorted by cell" do + expect(component.bulk_upload_errors.map(&:cell)).to eql(%w[A1 Z1 AB1]) + end + end + context "when a sales bulk upload" do let(:bulk_upload) { create(:bulk_upload, :sales) } let(:field) { :field_87 } From 524172f260c215f7c8ad154218dc9f73dfce926e Mon Sep 17 00:00:00 2001 From: natdeanlewissoftwire <94526761+natdeanlewissoftwire@users.noreply.github.com> Date: Tue, 17 Jan 2023 11:48:04 +0000 Subject: [PATCH 4/5] feat: add hint text and update test (#1171) --- app/models/form/lettings/questions/renewal.rb | 1 + spec/models/form/lettings/questions/renewal_spec.rb | 2 +- 2 files changed, 2 insertions(+), 1 deletion(-) diff --git a/app/models/form/lettings/questions/renewal.rb b/app/models/form/lettings/questions/renewal.rb index 1282984cc..edf9c1e7b 100644 --- a/app/models/form/lettings/questions/renewal.rb +++ b/app/models/form/lettings/questions/renewal.rb @@ -6,6 +6,7 @@ class Form::Lettings::Questions::Renewal < ::Form::Question @header = "Is this letting a renewal?" @type = "radio" @answer_options = ANSWER_OPTIONS + @hint_text = "A renewal is a letting to the same tenant in the same property" end ANSWER_OPTIONS = { diff --git a/spec/models/form/lettings/questions/renewal_spec.rb b/spec/models/form/lettings/questions/renewal_spec.rb index 820ff7c98..edb869d02 100644 --- a/spec/models/form/lettings/questions/renewal_spec.rb +++ b/spec/models/form/lettings/questions/renewal_spec.rb @@ -28,7 +28,7 @@ RSpec.describe Form::Lettings::Questions::Renewal, type: :model do end it "has the correct hint_text" do - expect(question.hint_text).to be_nil + expect(question.hint_text).to eq("A renewal is a letting to the same tenant in the same property") end it "has the correct answer_options" do From 52abc23c70b98d724a78ec3cc241f013d57495ed Mon Sep 17 00:00:00 2001 From: kosiakkatrina <54268893+kosiakkatrina@users.noreply.github.com> Date: Tue, 17 Jan 2023 11:52:59 +0000 Subject: [PATCH 5/5] Cldc 808 derived sales variables (#1184) * Add derived household fields * Derive household variables for sales logs * Refactor and fix wrong test names * Count everyone under 20 as children if relationship is "C" --- .../derived_variables/sales_log_variables.rb | 72 +++++++++++++++++++ ...0113091706_add_derived_household_fields.rb | 10 +++ db/schema.rb | 4 ++ spec/models/sales_log_spec.rb | 38 ++++++++++ 4 files changed, 124 insertions(+) create mode 100644 db/migrate/20230113091706_add_derived_household_fields.rb diff --git a/app/models/derived_variables/sales_log_variables.rb b/app/models/derived_variables/sales_log_variables.rb index a527ed3f0..b00a16b63 100644 --- a/app/models/derived_variables/sales_log_variables.rb +++ b/app/models/derived_variables/sales_log_variables.rb @@ -16,5 +16,77 @@ module DerivedVariables::SalesLogVariables self.mscharge = 0 end self.pcode1, self.pcode2 = postcode_full.split(" ") if postcode_full.present? + self.totchild = total_child + self.totadult = total_adult + total_elder + self.hhmemb = totchild + totadult + self.hhtype = household_type + end + +private + + def total_elder + ages = [age1, age2, age3, age4, age5, age6] + ages.count { |age| age.present? && age >= 60 } + end + + def total_child + (2..6).count do |i| + age = public_send("age#{i}") + relat = public_send("relat#{i}") + age.present? && ((age < 20 && %w[C].include?(relat))) + end + end + + def total_adult + total = age1.present? && age1.between?(16, 59) ? 1 : 0 + total + (2..6).count do |i| + age = public_send("age#{i}") + relat = public_send("relat#{i}") + age.present? && ((age.between?(20, 59) || age.between?(18, 19) && relat != "C")) + end + end + + def household_type + return unless total_elder && total_adult && totchild + + if only_one_elder? + 1 + elsif only_two_elders? + 2 + elsif only_one_adult? + 3 + elsif only_two_adults? + 4 + elsif one_adult_with_at_least_one_child? + 5 + elsif at_least_two_adults_with_at_least_one_child? + 6 + else + 9 + end + end + + def at_least_two_adults_with_at_least_one_child? + total_elder.zero? && total_adult >= 2 && totchild >= 1 + end + + def one_adult_with_at_least_one_child? + total_elder.zero? && total_adult == 1 && totchild >= 1 + end + + def only_two_adults? + total_elder.zero? && total_adult == 2 && totchild.zero? + end + + def only_one_adult? + total_elder.zero? && total_adult == 1 && totchild.zero? + end + + def only_two_elders? + total_elder == 2 && total_adult.zero? && totchild.zero? + end + + def only_one_elder? + total_elder == 1 && total_adult.zero? && totchild.zero? end end diff --git a/db/migrate/20230113091706_add_derived_household_fields.rb b/db/migrate/20230113091706_add_derived_household_fields.rb new file mode 100644 index 000000000..d364b60a8 --- /dev/null +++ b/db/migrate/20230113091706_add_derived_household_fields.rb @@ -0,0 +1,10 @@ +class AddDerivedHouseholdFields < ActiveRecord::Migration[7.0] + def change + change_table :sales_logs, bulk: true do |t| + t.column :hhmemb, :integer + t.column :totadult, :integer + t.column :totchild, :integer + t.column :hhtype, :integer + end + end +end diff --git a/db/schema.rb b/db/schema.rb index 87f656bc7..85c088b66 100644 --- a/db/schema.rb +++ b/db/schema.rb @@ -483,6 +483,10 @@ ActiveRecord::Schema[7.0].define(version: 2023_01_13_125117) do t.integer "hoday" t.integer "homonth" t.integer "hoyear" + t.integer "hhmemb" + t.integer "totadult" + t.integer "totchild" + t.integer "hhtype" t.integer "fromprop" t.integer "socprevten" t.integer "mortlen" diff --git a/spec/models/sales_log_spec.rb b/spec/models/sales_log_spec.rb index bad72db3b..a0efcf313 100644 --- a/spec/models/sales_log_spec.rb +++ b/spec/models/sales_log_spec.rb @@ -232,6 +232,44 @@ RSpec.describe SalesLog, type: :model do end end + context "when deriving household variables" do + let!(:household_lettings_log) do + described_class.create!({ + jointpur: 1, + hholdcount: 3, + relat2: "C", + relat3: "C", + relat4: "X", + relat5: "C", + age1: 22, + age2: 40, + age3: 19, + age4: 88, + age5: 14, + }) + end + + it "correctly derives and saves hhmemb" do + record_from_db = ActiveRecord::Base.connection.execute("select hhmemb from sales_logs where id=#{household_lettings_log.id}").to_a[0] + expect(record_from_db["hhmemb"]).to eq(5) + end + + it "correctly derives and saves totchild" do + record_from_db = ActiveRecord::Base.connection.execute("select totchild from sales_logs where id=#{household_lettings_log.id}").to_a[0] + expect(record_from_db["totchild"]).to eq(2) + end + + it "correctly derives and saves totadult" do + record_from_db = ActiveRecord::Base.connection.execute("select totadult from sales_logs where id=#{household_lettings_log.id}").to_a[0] + expect(record_from_db["totadult"]).to eq(3) + end + + it "correctly derives and saves hhtype" do + record_from_db = ActiveRecord::Base.connection.execute("select hhtype from sales_logs where id=#{household_lettings_log.id}").to_a[0] + expect(record_from_db["hhtype"]).to eq(9) + end + end + context "when saving previous address" do def check_previous_postcode_fields(postcode_field) record_from_db = ActiveRecord::Base.connection.execute("select #{postcode_field} from sales_logs where id=#{address_sales_log.id}").to_a[0]