From 2209bfec705caed022399a3e5cb383100f96471b Mon Sep 17 00:00:00 2001 From: oscar-richardson-softwire Date: Fri, 16 Jan 2026 16:54:42 +0000 Subject: [PATCH 1/5] Ask address and UPRN questions for 2026 and later logs --- app/models/derived_variables/lettings_log_variables.rb | 5 ++++- app/models/form/lettings/pages/address_fallback.rb | 2 +- app/models/form/lettings/pages/address_search.rb | 2 +- app/models/lettings_log.rb | 8 ++++++-- app/models/validations/property_validations.rb | 10 ++++++++++ .../validations/lettings/property_information.en.yml | 2 ++ 6 files changed, 24 insertions(+), 5 deletions(-) diff --git a/app/models/derived_variables/lettings_log_variables.rb b/app/models/derived_variables/lettings_log_variables.rb index 9ea820dc0..69daeb820 100644 --- a/app/models/derived_variables/lettings_log_variables.rb +++ b/app/models/derived_variables/lettings_log_variables.rb @@ -170,7 +170,10 @@ module DerivedVariables::LettingsLogVariables self.referral = 7 if referral_type == 6 self.referral = 16 if referral_type == 7 - reset_address_fields! if is_supported_housing? + if location_changed? + reset_address_fields! + self.la = nil + end set_checkbox_values! end diff --git a/app/models/form/lettings/pages/address_fallback.rb b/app/models/form/lettings/pages/address_fallback.rb index f7503e3af..8129bf821 100644 --- a/app/models/form/lettings/pages/address_fallback.rb +++ b/app/models/form/lettings/pages/address_fallback.rb @@ -3,7 +3,7 @@ class Form::Lettings::Pages::AddressFallback < ::Form::Page super @id = "address" @copy_key = "lettings.property_information.address" - @depends_on = [{ "is_supported_housing?" => false, "manual_address_entry_selected" => true }] + @depends_on = [{ "is_address_asked?" => true, "manual_address_entry_selected" => true }] @question_number = QUESTION_NUMBER_FROM_YEAR[form.start_date.year] || QUESTION_NUMBER_FROM_YEAR[QUESTION_NUMBER_FROM_YEAR.keys.max] end diff --git a/app/models/form/lettings/pages/address_search.rb b/app/models/form/lettings/pages/address_search.rb index 866018d45..59cc40d80 100644 --- a/app/models/form/lettings/pages/address_search.rb +++ b/app/models/form/lettings/pages/address_search.rb @@ -3,7 +3,7 @@ class Form::Lettings::Pages::AddressSearch < ::Form::Page super @id = "address_search" @copy_key = "sales.property_information.address_search" - @depends_on = [{ "is_supported_housing?" => false, "manual_address_entry_selected" => false }] + @depends_on = [{ "is_address_asked?" => true, "manual_address_entry_selected" => false }] @question_number = QUESTION_NUMBER_FROM_YEAR[form.start_date.year] || QUESTION_NUMBER_FROM_YEAR[QUESTION_NUMBER_FROM_YEAR.keys.max] end diff --git a/app/models/lettings_log.rb b/app/models/lettings_log.rb index 9c9894d32..5e84f06dc 100644 --- a/app/models/lettings_log.rb +++ b/app/models/lettings_log.rb @@ -184,7 +184,7 @@ class LettingsLog < Log end def la - if location + if (!form.start_year_2026_or_later? && location) || (form.start_year_2026_or_later? && !super) location.linked_local_authorities.active(form.start_date).first&.code || location.location_code else super @@ -192,7 +192,7 @@ class LettingsLog < Log end def postcode_full - if location + if (!form.start_year_2026_or_later? && location) || (form.start_year_2026_or_later? && !super) location.postcode else super @@ -773,6 +773,10 @@ class LettingsLog < Log rsnvac != 15 && rsnvac_was == 15 end + def is_address_asked? + form.start_year_2026_or_later? || !is_supported_housing? + end + private def reset_invalid_unresolved_log_fields! diff --git a/app/models/validations/property_validations.rb b/app/models/validations/property_validations.rb index c5ed9728a..d18ec9b44 100644 --- a/app/models/validations/property_validations.rb +++ b/app/models/validations/property_validations.rb @@ -50,6 +50,16 @@ module Validations::PropertyValidations error_message = I18n.t("validations.lettings.property.postcode_full.invalid") record.errors.add :postcode_full, :wrong_format, message: error_message end + + return unless record.form.start_year_2026_or_later? + + location_postcode = record.location&.postcode + return unless location_postcode + + if postcode != location_postcode + record.errors.add :uprn, I18n.t("validations.lettings.property.uprn.postcode_does_not_match_scheme_location_postcode") + record.errors.add :postcode_full, I18n.t("validations.lettings.property.postcode_full.does_not_match_scheme_location_postcode") + end end # see also: this validation in sales/property_validations.rb diff --git a/config/locales/validations/lettings/property_information.en.yml b/config/locales/validations/lettings/property_information.en.yml index 8f706c261..9eec4b2f7 100644 --- a/config/locales/validations/lettings/property_information.en.yml +++ b/config/locales/validations/lettings/property_information.en.yml @@ -6,6 +6,7 @@ en: invalid: "Enter a postcode in the correct format, for example AA1 1AA." not_in_england: "It looks like you have an entered a postcode outside of England. Only create logs for lettings in England." la_not_valid_for_date: "%{la} does not exist on the tenancy start date, due to a change in local authority names and boundaries. Please enter the local authority name in use on the tenancy start date" + does_not_match_scheme_location_postcode: "The postcode in the address does not match the postcode for the location in the scheme. Please review your answers to the address or UPRN question (whichever you answered) and the location question." rsnvac: non_temp_accommodation: "Answer cannot be re-let to tenant who occupied the same property as temporary accommodation as this accommodation is not temporary." referral_invalid: "Answer cannot be re-let to tenant who occupied the same property as temporary accommodation as a different source of referral for this letting." @@ -24,6 +25,7 @@ en: invalid: "UPRN must be 12 digits or less." not_in_england: "It looks like you have entered an address outside of England. Only create logs for lettings in England." la_not_valid_for_date: "%{la} does not exist on the tenancy start date, due to a change in local authority names and boundaries. Please enter the local authority name in use on the tenancy start date" + postcode_does_not_match_scheme_location_postcode: "The postcode in the address does not match the postcode for the location in the scheme. Please review your answers to the address or UPRN question (whichever you answered) and the location question." uprn_confirmation: # legacy question not_in_england: "It looks like you have entered an address outside of England. Only create logs for lettings in England." uprn_selection: From 70e23ef4b996241d6a1dd79fdf39aa3fd8254bba Mon Sep 17 00:00:00 2001 From: oscar-richardson-softwire Date: Tue, 20 Jan 2026 15:03:37 +0000 Subject: [PATCH 2/5] Fix page tests --- spec/models/form/lettings/pages/address_fallback_spec.rb | 2 +- spec/models/form/lettings/pages/address_search_spec.rb | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/spec/models/form/lettings/pages/address_fallback_spec.rb b/spec/models/form/lettings/pages/address_fallback_spec.rb index ffac6238e..c4f720ba3 100644 --- a/spec/models/form/lettings/pages/address_fallback_spec.rb +++ b/spec/models/form/lettings/pages/address_fallback_spec.rb @@ -24,6 +24,6 @@ RSpec.describe Form::Lettings::Pages::AddressFallback, type: :model do end it "has correct depends_on" do - expect(page.depends_on).to eq([{ "manual_address_entry_selected" => true, "is_supported_housing?" => false }]) + expect(page.depends_on).to eq([{ "manual_address_entry_selected" => true, "is_address_asked?" => true }]) end end diff --git a/spec/models/form/lettings/pages/address_search_spec.rb b/spec/models/form/lettings/pages/address_search_spec.rb index 86c6537a1..0bf54bae8 100644 --- a/spec/models/form/lettings/pages/address_search_spec.rb +++ b/spec/models/form/lettings/pages/address_search_spec.rb @@ -25,7 +25,7 @@ RSpec.describe Form::Lettings::Pages::AddressSearch, type: :model do end it "has correct depends_on" do - expect(page.depends_on).to eq([{ "is_supported_housing?" => false, "manual_address_entry_selected" => false }]) + expect(page.depends_on).to eq([{ "is_address_asked?" => true, "manual_address_entry_selected" => false }]) end it "has the correct question number" do From da33e4734939f9674fd1a885b302420f1923e664 Mon Sep 17 00:00:00 2001 From: oscar-richardson-softwire Date: Tue, 20 Jan 2026 15:13:47 +0000 Subject: [PATCH 3/5] Fix LA and postcode overrides --- app/models/lettings_log.rb | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/app/models/lettings_log.rb b/app/models/lettings_log.rb index 5e84f06dc..f650c0ff2 100644 --- a/app/models/lettings_log.rb +++ b/app/models/lettings_log.rb @@ -184,7 +184,7 @@ class LettingsLog < Log end def la - if (!form.start_year_2026_or_later? && location) || (form.start_year_2026_or_later? && !super) + if location && (!form.start_year_2026_or_later? || (form.start_year_2026_or_later? && !super)) location.linked_local_authorities.active(form.start_date).first&.code || location.location_code else super @@ -192,7 +192,7 @@ class LettingsLog < Log end def postcode_full - if (!form.start_year_2026_or_later? && location) || (form.start_year_2026_or_later? && !super) + if location && (!form.start_year_2026_or_later? || (form.start_year_2026_or_later? && !super)) location.postcode else super From b8ad350d491fb4f2fb60a8cece853acb4d6ca62b Mon Sep 17 00:00:00 2001 From: oscar-richardson-softwire Date: Tue, 20 Jan 2026 15:14:44 +0000 Subject: [PATCH 4/5] Fix resetting address fields and LA --- app/models/derived_variables/lettings_log_variables.rb | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/app/models/derived_variables/lettings_log_variables.rb b/app/models/derived_variables/lettings_log_variables.rb index 69daeb820..7fb818a25 100644 --- a/app/models/derived_variables/lettings_log_variables.rb +++ b/app/models/derived_variables/lettings_log_variables.rb @@ -170,7 +170,9 @@ module DerivedVariables::LettingsLogVariables self.referral = 7 if referral_type == 6 self.referral = 16 if referral_type == 7 - if location_changed? + if !form.start_year_2026_or_later? && is_supported_housing? + reset_address_fields! + elsif form.start_year_2026_or_later? && location_changed? reset_address_fields! self.la = nil end From c90f0de117932198ec19832299f5aa2dc19cb20b Mon Sep 17 00:00:00 2001 From: oscar-richardson-softwire Date: Tue, 20 Jan 2026 15:15:35 +0000 Subject: [PATCH 5/5] Add tests for resetting address fields and LA --- .../lettings_log_derived_fields_spec.rb | 135 ++++++++++++++++++ 1 file changed, 135 insertions(+) diff --git a/spec/models/lettings_log_derived_fields_spec.rb b/spec/models/lettings_log_derived_fields_spec.rb index ced14af9f..fddb97188 100644 --- a/spec/models/lettings_log_derived_fields_spec.rb +++ b/spec/models/lettings_log_derived_fields_spec.rb @@ -1372,4 +1372,139 @@ RSpec.describe LettingsLog, type: :model do expect { log.set_derived_fields! }.to change(log, :beds).to nil end end + + describe "resetting address fields and LA" do + let(:uprn) { "123456789" } + let(:uprn_known) { 1 } # A value of 1 is necessary for this test as there is separate logic that resets `uprn` if `uprn_known` is 0. + let(:uprn_confirmed) { 1 } # A value of 1 is necessary for this test as there is separate logic that resets the address fields and LA if `uprn_confirmed` is 0 (and `uprn_known` is 1). + let(:address_line1) { "1 Test Street" } + let(:address_line2) { "Testville" } + let(:town_or_city) { "Testford" } + let(:county) { "Testshire" } + let(:postcode_full) { "SW1 1AA" } + let(:la) { "Test LA" } + let(:manual_address_entry_selected) { false } # A value of `false` is necessary for this test as there is separate logic that resets some of the UPRN fields if `manual_address_entry_selected` is `false`. + + context "when it is 2025", metadata: { year: 25 } do + let(:startdate) { collection_start_date_for_year(2025) } + + around do |example| + Timecop.freeze(collection_start_date_for_year(2025)) do + Singleton.__init__(FormHandler) + + log.save! # This is necessary to prevent `startdate_changed?` returning true; if this happens, some separate logic runs that resets LA to nil. + + log.assign_attributes(uprn:, uprn_known:, uprn_confirmed:, address_line1:, address_line2:, town_or_city:, county:, postcode_full:, la:, manual_address_entry_selected:) + + example.run + end + end + + context "when the log is marked as general needs housing" do + before do + log.needstype = 1 + end + + it "does not reset the address fields" do + expect { log.set_derived_fields! } + .to not_change(log, :uprn) + .and not_change(log, :uprn_known) + .and not_change(log, :uprn_confirmed) + .and not_change(log, :address_line1) + .and not_change(log, :address_line2) + .and not_change(log, :town_or_city) + .and not_change(log, :county) + .and not_change(log, :postcode_full) + end + + it "does not reset LA" do + expect { log.set_derived_fields! }.to not_change(log, :la) + end + end + + context "when the log is marked as supported housing" do + before do + log.needstype = 2 + end + + it "resets the address fields to nil" do + expect { log.set_derived_fields! } + .to change(log, :uprn).from(uprn).to(nil) + .and change(log, :uprn_known).from(uprn_known).to(nil) + .and change(log, :uprn_confirmed).from(uprn_confirmed).to(nil) + .and change(log, :address_line1).from(address_line1).to(nil) + .and change(log, :address_line2).from(address_line2).to(nil) + .and change(log, :town_or_city).from(town_or_city).to(nil) + .and change(log, :county).from(county).to(nil) + .and change(log, :postcode_full).from(postcode_full).to(nil) + end + + it "does not reset LA" do + expect { log.set_derived_fields! }.to not_change(log, :la) + end + end + end + + context "when it is 2026", metadata: { year: 26 } do + let(:startdate) { collection_start_date_for_year(2026) } + let(:location_a) { create(:location) } + let(:location_b) { create(:location) } + + around do |example| + Timecop.freeze(collection_start_date_for_year(2026)) do + Singleton.__init__(FormHandler) + example.run + end + end + + before do + allow(location_a).to receive(:lookup_postcode!).and_return(nil) + + log.location = location_a + log.save! + + log.assign_attributes(uprn:, uprn_known:, uprn_confirmed:, address_line1:, address_line2:, town_or_city:, county:, postcode_full:, la:, manual_address_entry_selected:) + end + + context "when the location is not changed" do + it "does not reset the address fields" do + expect { log.set_derived_fields! } + .to not_change(log, :uprn) + .and not_change(log, :uprn_known) + .and not_change(log, :uprn_confirmed) + .and not_change(log, :address_line1) + .and not_change(log, :address_line2) + .and not_change(log, :town_or_city) + .and not_change(log, :county) + .and not_change(log, :postcode_full) + end + + it "does not reset LA" do + expect { log.set_derived_fields! }.to not_change(log, :la) + end + end + + context "when the location is changed" do + before do + log.location = location_b + end + + it "resets the address fields to nil" do + expect { log.set_derived_fields! } + .to change(log, :uprn).from(uprn).to(nil) + .and change(log, :uprn_known).from(uprn_known).to(nil) + .and change(log, :uprn_confirmed).from(uprn_confirmed).to(nil) + .and change(log, :address_line1).from(address_line1).to(nil) + .and change(log, :address_line2).from(address_line2).to(nil) + .and change(log, :town_or_city).from(town_or_city).to(nil) + .and change(log, :county).from(county).to(nil) + .and change(log, :postcode_full).from(postcode_full).to(nil) + end + + it "resets LA to nil" do + expect { log.set_derived_fields! }.to change(log, :la).from(la).to(nil) + end + end + end + end end