diff --git a/app/models/form/sales/questions/postcode_known.rb b/app/models/form/sales/questions/postcode_known.rb index 2332af6b2..208f8df22 100644 --- a/app/models/form/sales/questions/postcode_known.rb +++ b/app/models/form/sales/questions/postcode_known.rb @@ -9,6 +9,16 @@ class Form::Sales::Questions::PostcodeKnown < ::Form::Question @conditional_for = { "postcode_full" => [0], } + @hidden_in_check_answers = { + "depends_on" => [ + { + "pcodenk" => 0, + }, + { + "pcodenk" => 1, + }, + ], + } end ANSWER_OPTIONS = { diff --git a/app/models/lettings_log.rb b/app/models/lettings_log.rb index 0041f3200..9b1708613 100644 --- a/app/models/lettings_log.rb +++ b/app/models/lettings_log.rb @@ -607,10 +607,6 @@ private self[la_key] = inferred_la if inferred_la.present? end - def reset_location_fields! - reset_location(is_la_inferred, "la", "is_la_inferred", "postcode_full", 1) - end - def get_has_benefits HAS_BENEFITS_OPTIONS.include?(hb) ? 1 : 0 end diff --git a/app/models/log.rb b/app/models/log.rb index 798b78af7..0d0df6451 100644 --- a/app/models/log.rb +++ b/app/models/log.rb @@ -105,6 +105,10 @@ private string.present? ? string.upcase.gsub(/\s+/, "") : string end + def reset_location_fields! + 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 diff --git a/app/models/sales_log.rb b/app/models/sales_log.rb index 22f750148..c5c51578b 100644 --- a/app/models/sales_log.rb +++ b/app/models/sales_log.rb @@ -21,7 +21,9 @@ class SalesLog < Log validates_with SalesLogValidator before_validation :set_derived_fields! before_validation :reset_invalidated_dependent_fields! + before_validation :process_postcode_changes!, if: :postcode_full_changed? before_validation :process_previous_postcode_changes!, if: :ppostcode_full_changed? + before_validation :reset_location_fields!, unless: :postcode_known? 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)) } @@ -135,6 +137,18 @@ class SalesLog < Log ppcodenk&.zero? end + def postcode_known? + pcodenk&.zero? + end + + def postcode_full=(postcode) + if postcode + super UKPostcode.parse(postcode).to_s + else + super nil + end + end + def process_postcode(postcode, postcode_known_key, la_inferred_key, la_key) return if postcode.blank? @@ -151,4 +165,9 @@ class SalesLog < Log def mortgage_not_used? mortgageused == 2 end + + def process_postcode_changes! + self.postcode_full = upcase_and_remove_whitespace(postcode_full) + process_postcode(postcode_full, "pcodenk", "is_la_inferred", "la") + end end diff --git a/spec/factories/sales_log.rb b/spec/factories/sales_log.rb index 23dc0c5fe..105008350 100644 --- a/spec/factories/sales_log.rb +++ b/spec/factories/sales_log.rb @@ -57,7 +57,7 @@ FactoryBot.define do income2nk { 0 } income2 { 10_000 } inc2mort { 1 } - la_known { "1" } + la_known { 1 } la { "E09000003" } savingsnk { 1 } prevown { 1 } @@ -96,6 +96,8 @@ FactoryBot.define do mscharge_known { 1 } mscharge { 100 } mortlen { 10 } + pcodenk { 1 } + is_la_inferred { false } end end end diff --git a/spec/models/form/sales/questions/postcode_known_spec.rb b/spec/models/form/sales/questions/postcode_known_spec.rb index a9d04d557..b6c404c56 100644 --- a/spec/models/form/sales/questions/postcode_known_spec.rb +++ b/spec/models/form/sales/questions/postcode_known_spec.rb @@ -47,4 +47,13 @@ RSpec.describe Form::Sales::Questions::PostcodeKnown, type: :model do it "has the correct hint" do expect(question.hint_text).to be_nil end + + it "has the correct hidden_in_check_answers" do + expect(question.hidden_in_check_answers).to eq({ + "depends_on" => [ + { "pcodenk" => 0 }, + { "pcodenk" => 1 }, + ], + }) + end end diff --git a/spec/models/form_handler_spec.rb b/spec/models/form_handler_spec.rb index db8c90aaa..4365eedcb 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(137) + expect(form.pages.count).to eq(138) 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(137) + expect(form.pages.count).to eq(138) expect(form.name).to eq("2021_2022_sales") end end diff --git a/spec/models/sales_log_spec.rb b/spec/models/sales_log_spec.rb index 8f46db42d..c470bc5d3 100644 --- a/spec/models/sales_log_spec.rb +++ b/spec/models/sales_log_spec.rb @@ -129,6 +129,102 @@ RSpec.describe SalesLog, type: :model do end end + context "when saving addresses" do + 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 + + def check_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 + + let!(:address_sales_log) do + FactoryBot.create( + :sales_log, + :completed, + managing_organisation: owning_organisation, + owning_organisation:, + created_by: created_by_user, + pcodenk: 0, + postcode_full: "M1 1AE", + ) + end + + def check_property_postcode_fields + check_postcode_fields("postcode_full") + end + + it "correctly formats previous postcode" do + address_sales_log.update!(postcode_full: "M1 1AE") + check_property_postcode_fields + + address_sales_log.update!(postcode_full: "m1 1ae") + check_property_postcode_fields + + address_sales_log.update!(postcode_full: "m11Ae") + check_property_postcode_fields + + address_sales_log.update!(postcode_full: "m11ae") + check_property_postcode_fields + end + + it "correctly infers la" do + record_from_db = ActiveRecord::Base.connection.execute("select la from sales_logs where id=#{address_sales_log.id}").to_a[0] + expect(address_sales_log.la).to eq("E08000003") + expect(record_from_db["la"]).to eq("E08000003") + end + + it "errors if the property postcode is emptied" do + expect { address_sales_log.update!({ postcode_full: "" }) } + .to raise_error(ActiveRecord::RecordInvalid, /#{I18n.t("validations.postcode")}/) + end + + it "errors if the property postcode is not valid" do + expect { address_sales_log.update!({ postcode_full: "invalid_postcode" }) } + .to raise_error(ActiveRecord::RecordInvalid, /#{I18n.t("validations.postcode")}/) + end + + context "when the local authority lookup times out" do + before do + allow(Timeout).to receive(:timeout).and_raise(Timeout::Error) + end + + it "logs a warning" do + expect(Rails.logger).to receive(:warn).with("Postcodes.io lookup timed out") + address_sales_log.update!({ pcodenk: 1, postcode_full: "M1 1AD" }) + end + end + + it "correctly resets all fields if property postcode not known" do + address_sales_log.update!({ pcodenk: 1 }) + + record_from_db = ActiveRecord::Base.connection.execute("select la, postcode_full from sales_logs where id=#{address_sales_log.id}").to_a[0] + expect(record_from_db["postcode_full"]).to eq(nil) + expect(address_sales_log.la).to eq(nil) + expect(record_from_db["la"]).to eq(nil) + end + + it "changes the LA if property postcode changes from not known to known and provided" do + address_sales_log.update!({ pcodenk: 1 }) + address_sales_log.update!({ la: "E09000033" }) + + record_from_db = ActiveRecord::Base.connection.execute("select la, postcode_full from sales_logs where id=#{address_sales_log.id}").to_a[0] + expect(record_from_db["postcode_full"]).to eq(nil) + expect(address_sales_log.la).to eq("E09000033") + expect(record_from_db["la"]).to eq("E09000033") + + address_sales_log.update!({ pcodenk: 0, postcode_full: "M1 1AD" }) + + record_from_db = ActiveRecord::Base.connection.execute("select la, postcode_full from sales_logs where id=#{address_sales_log.id}").to_a[0] + expect(record_from_db["postcode_full"]).to eq("M1 1AD") + expect(address_sales_log.la).to eq("E08000003") + expect(record_from_db["la"]).to eq("E08000003") + 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]