From 1c8cbfa020720242cef8d6a7b2c0ab6869a61631 Mon Sep 17 00:00:00 2001 From: kosiakkatrina <54268893+kosiakkatrina@users.noreply.github.com> Date: Fri, 23 Dec 2022 16:56:04 +0000 Subject: [PATCH] Cldc 1488 last accomodation (#1125) * Add postcode fields * Add previous postcode page and questions * Add last accommodation page to household situation subsection * add previous la known to the db * infer correct location fields * styling --- .../form/sales/pages/last_accommodation.rb | 16 +++++ .../form/sales/questions/previous_postcode.rb | 23 +++++++ .../questions/previous_postcode_known.rb | 19 ++++++ .../sales/subsections/household_situation.rb | 1 + app/models/lettings_log.rb | 28 -------- app/models/log.rb | 28 ++++++++ app/models/sales_log.rb | 24 +++++++ .../20221223105623_add_postcode_fields.rb | 13 ++++ db/schema.rb | 7 ++ spec/factories/sales_log.rb | 2 +- .../sales/pages/last_accommodation_spec.rb | 33 ++++++++++ .../questions/previous_postcode_known_spec.rb | 46 +++++++++++++ .../sales/questions/previous_postcode_spec.rb | 58 ++++++++++++++++ .../subsections/household_situation_spec.rb | 1 + spec/models/sales_log_spec.rb | 66 +++++++++++++++++++ 15 files changed, 336 insertions(+), 29 deletions(-) create mode 100644 app/models/form/sales/pages/last_accommodation.rb create mode 100644 app/models/form/sales/questions/previous_postcode.rb create mode 100644 app/models/form/sales/questions/previous_postcode_known.rb create mode 100644 db/migrate/20221223105623_add_postcode_fields.rb create mode 100644 spec/models/form/sales/pages/last_accommodation_spec.rb create mode 100644 spec/models/form/sales/questions/previous_postcode_known_spec.rb create mode 100644 spec/models/form/sales/questions/previous_postcode_spec.rb diff --git a/app/models/form/sales/pages/last_accommodation.rb b/app/models/form/sales/pages/last_accommodation.rb new file mode 100644 index 000000000..43ccd276e --- /dev/null +++ b/app/models/form/sales/pages/last_accommodation.rb @@ -0,0 +1,16 @@ +class Form::Sales::Pages::LastAccommodation < ::Form::Page + def initialize(id, hsh, subsection) + super + @id = "last_accommodation" + @header = "" + @description = "" + @subsection = subsection + end + + def questions + @questions ||= [ + Form::Sales::Questions::PreviousPostcodeKnown.new(nil, nil, self), + Form::Sales::Questions::PreviousPostcode.new(nil, nil, self), + ] + end +end diff --git a/app/models/form/sales/questions/previous_postcode.rb b/app/models/form/sales/questions/previous_postcode.rb new file mode 100644 index 000000000..ea4cb82ed --- /dev/null +++ b/app/models/form/sales/questions/previous_postcode.rb @@ -0,0 +1,23 @@ +class Form::Sales::Questions::PreviousPostcode < ::Form::Question + def initialize(id, hsh, page) + super + @id = "ppostcode_full" + @check_answer_label = "Postcode of buyer 1’s last settled accommodation" + @header = "Postcode" + @page = page + @type = "text" + @width = 5 + @hint_text = "This is also known as the household’s 'last settled home'" + @inferred_check_answers_value = { + "condition" => { + "ppcodenk" => 1, + }, + "value" => "Not known", + } + @inferred_answers = { + "prevloc" => { + "is_previous_la_inferred" => true, + }, + } + end +end diff --git a/app/models/form/sales/questions/previous_postcode_known.rb b/app/models/form/sales/questions/previous_postcode_known.rb new file mode 100644 index 000000000..77da10446 --- /dev/null +++ b/app/models/form/sales/questions/previous_postcode_known.rb @@ -0,0 +1,19 @@ +class Form::Sales::Questions::PreviousPostcodeKnown < ::Form::Question + def initialize(id, hsh, page) + super + @id = "ppcodenk" + @check_answer_label = "Buyer 1’s last settled accommodation" + @header = "Do you know the postcode of buyer 1’s last settled accommodation?" + @type = "radio" + @answer_options = ANSWER_OPTIONS + @page = page + @conditional_for = { + "ppostcode_full" => [0], + } + end + + ANSWER_OPTIONS = { + "0" => { "value" => "Yes" }, + "1" => { "value" => "No" }, + }.freeze +end diff --git a/app/models/form/sales/subsections/household_situation.rb b/app/models/form/sales/subsections/household_situation.rb index 2be48f68c..45a12a2a0 100644 --- a/app/models/form/sales/subsections/household_situation.rb +++ b/app/models/form/sales/subsections/household_situation.rb @@ -10,6 +10,7 @@ class Form::Sales::Subsections::HouseholdSituation < ::Form::Subsection def pages @pages ||= [ Form::Sales::Pages::BuyersOrganisations.new(nil, nil, self), + Form::Sales::Pages::LastAccommodation.new(nil, nil, self), ] end end diff --git a/app/models/lettings_log.rb b/app/models/lettings_log.rb index d9375d5fd..0041f3200 100644 --- a/app/models/lettings_log.rb +++ b/app/models/lettings_log.rb @@ -521,8 +521,6 @@ class LettingsLog < Log private - PIO = PostcodeService.new - def reset_derived_questions dependent_questions = { waityear: [{ key: :renewal, value: 0 }], referral: [{ key: :renewal, value: 0 }], @@ -600,11 +598,6 @@ private process_postcode(postcode_full, "postcode_known", "is_la_inferred", "la") end - def process_previous_postcode_changes! - self.ppostcode_full = upcase_and_remove_whitespace(ppostcode_full) - process_postcode(ppostcode_full, "ppcodenk", "is_previous_la_inferred", "prevloc") - end - def process_postcode(postcode, postcode_known_key, la_inferred_key, la_key) return if postcode.blank? @@ -618,23 +611,6 @@ private reset_location(is_la_inferred, "la", "is_la_inferred", "postcode_full", 1) end - def reset_previous_location_fields! - reset_location(is_previous_la_inferred, "prevloc", "is_previous_la_inferred", "ppostcode_full", previous_la_known) - end - - def reset_location(is_inferred, la_key, is_inferred_key, postcode_key, is_la_known) - if is_inferred || is_la_known != 1 - self[la_key] = nil - end - self[is_inferred_key] = false - self[postcode_key] = nil - end - - def get_inferred_la(postcode) - result = PIO.lookup(postcode) - result[:location_code] if result - end - def get_has_benefits HAS_BENEFITS_OPTIONS.include?(hb) ? 1 : 0 end @@ -687,10 +663,6 @@ private (value * 52 / num_of_weeks).round(2) end - def upcase_and_remove_whitespace(string) - string.present? ? string.upcase.gsub(/\s+/, "") : string - end - def fully_wheelchair_accessible? housingneeds_type.present? && housingneeds_type.zero? end diff --git a/app/models/log.rb b/app/models/log.rb index e9dc9c69a..798b78af7 100644 --- a/app/models/log.rb +++ b/app/models/log.rb @@ -88,4 +88,32 @@ private update!(created_by: nil) end + + PIO = PostcodeService.new + + def process_previous_postcode_changes! + self.ppostcode_full = upcase_and_remove_whitespace(ppostcode_full) + process_postcode(ppostcode_full, "ppcodenk", "is_previous_la_inferred", "prevloc") + end + + def get_inferred_la(postcode) + result = PIO.lookup(postcode) + result[:location_code] if result + end + + def upcase_and_remove_whitespace(string) + string.present? ? string.upcase.gsub(/\s+/, "") : string + end + + def reset_previous_location_fields! + reset_location(is_previous_la_inferred, "prevloc", "is_previous_la_inferred", "ppostcode_full", previous_la_known) + end + + def reset_location(is_inferred, la_key, is_inferred_key, postcode_key, is_la_known) + if is_inferred || is_la_known != 1 + self[la_key] = nil + end + self[is_inferred_key] = false + self[postcode_key] = nil + end end diff --git a/app/models/sales_log.rb b/app/models/sales_log.rb index 65175a802..86c23e0ce 100644 --- a/app/models/sales_log.rb +++ b/app/models/sales_log.rb @@ -2,6 +2,7 @@ class SalesLogValidator < ActiveModel::Validator include Validations::Sales::HouseholdValidations include Validations::SharedValidations include Validations::Sales::FinancialValidations + include Validations::LocalAuthorityValidations def validate(record) validation_methods = public_methods.select { |method| method.starts_with?("validate_") } @@ -20,6 +21,8 @@ class SalesLog < Log validates_with SalesLogValidator before_validation :set_derived_fields! before_validation :reset_invalidated_dependent_fields! + before_validation :process_previous_postcode_changes!, if: :ppostcode_full_changed? + before_validation :reset_previous_location_fields!, unless: :previous_postcode_known? scope :filter_by_year, ->(year) { where(saledate: Time.zone.local(year.to_i, 4, 1)...Time.zone.local(year.to_i + 1, 4, 1)) } scope :search_by, ->(param) { filter_by_id(param) } @@ -119,4 +122,25 @@ class SalesLog < Log def is_type_discount? type == 18 end + + def ppostcode_full=(postcode) + if postcode + super UKPostcode.parse(postcode).to_s + else + super nil + end + end + + def previous_postcode_known? + ppcodenk&.zero? + end + + def process_postcode(postcode, postcode_known_key, la_inferred_key, la_key) + return if postcode.blank? + + self[postcode_known_key] = 0 + inferred_la = get_inferred_la(postcode) + self[la_inferred_key] = inferred_la.present? + self[la_key] = inferred_la if inferred_la.present? + end end diff --git a/db/migrate/20221223105623_add_postcode_fields.rb b/db/migrate/20221223105623_add_postcode_fields.rb new file mode 100644 index 000000000..66ab7deef --- /dev/null +++ b/db/migrate/20221223105623_add_postcode_fields.rb @@ -0,0 +1,13 @@ +class AddPostcodeFields < ActiveRecord::Migration[7.0] + def change + change_table :sales_logs, bulk: true do |t| + t.column :ppostcode_full, :string + t.column :is_previous_la_inferred, :boolean + t.column :ppcodenk, :integer + t.column :ppostc1, :string + t.column :ppostc2, :string + t.column :prevloc, :string + t.column :previous_la_known, :boolean + end + end +end diff --git a/db/schema.rb b/db/schema.rb index e87ce4d18..6eabf4ec0 100644 --- a/db/schema.rb +++ b/db/schema.rb @@ -442,6 +442,13 @@ ActiveRecord::Schema[7.0].define(version: 2023_01_04_093057) do t.integer "proplen" t.integer "wheel_value_check" t.integer "hhregresstill" + t.string "ppostcode_full" + t.boolean "is_previous_la_inferred" + t.integer "ppcodenk" + t.string "ppostc1" + t.string "ppostc2" + t.string "prevloc" + t.boolean "previous_la_known" t.index ["created_by_id"], name: "index_sales_logs_on_created_by_id" t.index ["managing_organisation_id"], name: "index_sales_logs_on_managing_organisation_id" t.index ["owning_organisation_id"], name: "index_sales_logs_on_owning_organisation_id" diff --git a/spec/factories/sales_log.rb b/spec/factories/sales_log.rb index 966022a1a..32dd573df 100644 --- a/spec/factories/sales_log.rb +++ b/spec/factories/sales_log.rb @@ -77,9 +77,9 @@ FactoryBot.define do pregla { 1 } pregother { 1 } pregghb { 1 } - disabled { 1 } hhregres { 1 } hhregresstill { 4 } + ppcodenk { 1 } end end end diff --git a/spec/models/form/sales/pages/last_accommodation_spec.rb b/spec/models/form/sales/pages/last_accommodation_spec.rb new file mode 100644 index 000000000..6e4a6468c --- /dev/null +++ b/spec/models/form/sales/pages/last_accommodation_spec.rb @@ -0,0 +1,33 @@ +require "rails_helper" + +RSpec.describe Form::Sales::Pages::LastAccommodation, 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[ppcodenk ppostcode_full]) + end + + it "has the correct id" do + expect(page.id).to eq("last_accommodation") + end + + it "has the correct header" do + expect(page.header).to eq("") + end + + it "has the correct description" do + expect(page.description).to eq("") + end + + it "has correct depends_on" do + expect(page.depends_on).to be_nil + end +end diff --git a/spec/models/form/sales/questions/previous_postcode_known_spec.rb b/spec/models/form/sales/questions/previous_postcode_known_spec.rb new file mode 100644 index 000000000..887aa9abe --- /dev/null +++ b/spec/models/form/sales/questions/previous_postcode_known_spec.rb @@ -0,0 +1,46 @@ +require "rails_helper" + +RSpec.describe Form::Sales::Questions::PreviousPostcodeKnown, type: :model do + subject(:question) { described_class.new(question_id, question_definition, page) } + + let(:question_id) { nil } + let(:question_definition) { nil } + let(:page) { instance_double(Form::Page) } + + it "has correct page" do + expect(question.page).to eq(page) + end + + it "has the correct id" do + expect(question.id).to eq("ppcodenk") + end + + it "has the correct header" do + expect(question.header).to eq("Do you know the postcode of buyer 1’s last settled accommodation?") + end + + it "has the correct check_answer_label" do + expect(question.check_answer_label).to eq("Buyer 1’s last settled accommodation") + end + + it "has the correct type" do + expect(question.type).to eq("radio") + end + + it "is not marked as derived" do + expect(question.derived?).to be false + end + + it "has the correct answer_options" do + expect(question.answer_options).to eq({ + "0" => { "value" => "Yes" }, + "1" => { "value" => "No" }, + }) + end + + it "has correct conditional for" do + expect(question.conditional_for).to eq({ + "ppostcode_full" => [0], + }) + end +end diff --git a/spec/models/form/sales/questions/previous_postcode_spec.rb b/spec/models/form/sales/questions/previous_postcode_spec.rb new file mode 100644 index 000000000..73435ed11 --- /dev/null +++ b/spec/models/form/sales/questions/previous_postcode_spec.rb @@ -0,0 +1,58 @@ +require "rails_helper" + +RSpec.describe Form::Sales::Questions::PreviousPostcode, type: :model do + subject(:question) { described_class.new(question_id, question_definition, page) } + + let(:question_id) { nil } + let(:question_definition) { nil } + let(:page) { instance_double(Form::Page) } + + it "has correct page" do + expect(question.page).to eq(page) + end + + it "has the correct id" do + expect(question.id).to eq("ppostcode_full") + end + + it "has the correct header" do + expect(question.header).to eq("Postcode") + end + + it "has the correct check_answer_label" do + expect(question.check_answer_label).to eq("Postcode of buyer 1’s last settled accommodation") + end + + it "has the correct type" do + expect(question.type).to eq("text") + end + + it "is not marked as derived" do + expect(question.derived?).to be false + end + + it "has the correct hint" do + expect(question.hint_text).to eq("This is also known as the household’s 'last settled home'") + end + + it "has the correct width" do + expect(question.width).to eq(5) + end + + it "has the correct inferred_answers" do + expect(question.inferred_answers).to eq({ + "prevloc" => { + "is_previous_la_inferred" => true, + }, + }) + end + + it "has the correct inferred_check_answers_value" do + expect(question.inferred_check_answers_value).to eq({ + "condition" => { + "ppcodenk" => 1, + }, + "value" => "Not known", + }) + end +end diff --git a/spec/models/form/sales/subsections/household_situation_spec.rb b/spec/models/form/sales/subsections/household_situation_spec.rb index 8473971ef..fefd60013 100644 --- a/spec/models/form/sales/subsections/household_situation_spec.rb +++ b/spec/models/form/sales/subsections/household_situation_spec.rb @@ -15,6 +15,7 @@ RSpec.describe Form::Sales::Subsections::HouseholdSituation, type: :model do expect(household_characteristics.pages.map(&:id)).to eq( %w[ buyers_organisations + last_accommodation ], ) end diff --git a/spec/models/sales_log_spec.rb b/spec/models/sales_log_spec.rb index 9e618a10e..5942b3d84 100644 --- a/spec/models/sales_log_spec.rb +++ b/spec/models/sales_log_spec.rb @@ -105,4 +105,70 @@ RSpec.describe SalesLog, type: :model do expect(record_from_db["exyear"]).to eq(2022) 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] + expect(address_sales_log[postcode_field]).to eq("M1 1AE") + expect(record_from_db[postcode_field]).to eq("M1 1AE") + end + + before do + stub_request(:get, /api.postcodes.io/) + .to_return(status: 200, body: "{\"status\":200,\"result\":{\"admin_district\":\"Manchester\", \"codes\":{\"admin_district\": \"E08000003\"}}}", headers: {}) + end + + let!(:address_sales_log) do + described_class.create({ + managing_organisation: owning_organisation, + owning_organisation:, + created_by: created_by_user, + ppcodenk: 1, + ppostcode_full: "M1 1AE", + }) + end + + def previous_postcode_fields + check_previous_postcode_fields("ppostcode_full") + end + + it "correctly formats previous postcode" do + address_sales_log.update!(ppostcode_full: "M1 1AE") + previous_postcode_fields + + address_sales_log.update!(ppostcode_full: "m1 1ae") + previous_postcode_fields + + address_sales_log.update!(ppostcode_full: "m11Ae") + previous_postcode_fields + + address_sales_log.update!(ppostcode_full: "m11ae") + previous_postcode_fields + end + + it "correctly infers prevloc" do + record_from_db = ActiveRecord::Base.connection.execute("select prevloc from sales_logs where id=#{address_sales_log.id}").to_a[0] + expect(address_sales_log.prevloc).to eq("E08000003") + expect(record_from_db["prevloc"]).to eq("E08000003") + end + + it "errors if the previous postcode is emptied" do + expect { address_sales_log.update!({ ppostcode_full: "" }) } + .to raise_error(ActiveRecord::RecordInvalid, /#{I18n.t("validations.postcode")}/) + end + + it "errors if the previous postcode is not valid" do + expect { address_sales_log.update!({ ppostcode_full: "invalid_postcode" }) } + .to raise_error(ActiveRecord::RecordInvalid, /#{I18n.t("validations.postcode")}/) + end + + it "correctly resets all fields if previous postcode not known" do + address_sales_log.update!({ ppcodenk: 1 }) + + record_from_db = ActiveRecord::Base.connection.execute("select prevloc, ppostcode_full from sales_logs where id=#{address_sales_log.id}").to_a[0] + expect(record_from_db["ppostcode_full"]).to eq(nil) + expect(address_sales_log.prevloc).to eq(nil) + expect(record_from_db["prevloc"]).to eq(nil) + end + end end