Browse Source

CLDC-3826 Add LA changes for 2025 (#2888)

* Add LA changes for 2025

* Add missing soft validation copy

* Add local authority links and update seed

* Only display name once in the locations if only Ecode has changed

* lint
pull/2906/head
kosiakkatrina 1 week ago committed by GitHub
parent
commit
7a7abc842c
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
  1. 2
      app/helpers/locations_helper.rb
  2. 36
      app/models/log.rb
  3. 5
      config/local_authorities_data/2025_local_authorities.csv
  4. 5
      config/local_authorities_data/local_authority_links_2025.csv
  5. 8
      config/locales/forms/2025/lettings/soft_validations.en.yml
  6. 16
      db/seeds.rb
  7. 23
      spec/helpers/locations_helper_spec.rb
  8. 120
      spec/models/sales_log_spec.rb

2
app/helpers/locations_helper.rb

@ -150,7 +150,7 @@ private
def formatted_local_authority_timeline(location)
sorted_linked_authorities = location.linked_local_authorities.sort_by(&:start_date)
return sorted_linked_authorities.first["name"] if sorted_linked_authorities.count == 1
return sorted_linked_authorities.first["name"] if sorted_linked_authorities.count == 1 || sorted_linked_authorities.map(&:name).uniq.count == 1
sorted_linked_authorities.map { |linked_local_authority|
formatted_start_date = linked_local_authority.start_date.year == 2021 ? "until" : "#{linked_local_authority.start_date&.to_formatted_s(:govuk_date)} -"

36
app/models/log.rb

@ -343,31 +343,27 @@ private
PIO = PostcodeService.new
LA_CHANGES = {
"E07000027" => "E06000064", # Barrow-in-Furness => Westmorland and Furness
"E07000030" => "E06000064", # Eden => Westmorland and Furness
"E07000031" => "E06000064", # South Lakeland => Westmorland and Furness
"E07000026" => "E06000063", # Allerdale => Cumberland
"E07000028" => "E06000063", # Carlisle => Cumberland
"E07000029" => "E06000063", # Copeland => Cumberland
"E07000163" => "E06000065", # Craven => North Yorkshire
"E07000164" => "E06000065", # Hambleton => North Yorkshire
"E07000165" => "E06000065", # Harrogate => North Yorkshire
"E07000166" => "E06000065", # Richmondshire => North Yorkshire
"E07000167" => "E06000065", # Ryedale => North Yorkshire
"E07000168" => "E06000065", # Scarborough => North Yorkshire
"E07000169" => "E06000065", # Selby => North Yorkshire
"E07000187" => "E06000066", # Mendip => Somerset
"E07000188" => "E06000066", # Sedgemoor => Somerset
"E07000246" => "E06000066", # Somerset West and Taunton => Somerset
"E07000189" => "E06000066", # South Somerset => Somerset
2025 => {
"E08000016" => "E08000038", # Barnsley
"E08000019" => "E08000039", # Sheffield
},
}.freeze
BACKWARDS_LA_CHANGES = {
2024 => {
"E08000038" => "E08000016", # Barnsley
"E08000039" => "E08000019", # Sheffield
},
}.freeze
def get_inferred_la(postcode)
result = PIO.lookup(postcode)
location_code = result[:location_code] if result
if LA_CHANGES.key?(location_code) && form.start_date.year >= 2023
LA_CHANGES[location_code]
elsif !(LA_CHANGES.value?(location_code) && form.start_date.year < 2023)
if LA_CHANGES[form.start_date.year]&.key?(location_code)
LA_CHANGES[form.start_date.year][location_code]
elsif BACKWARDS_LA_CHANGES[form.start_date.year]&.key?(location_code)
BACKWARDS_LA_CHANGES[form.start_date.year][location_code]
elsif !LA_CHANGES.value?(location_code)
location_code
end
end

5
config/local_authorities_data/2025_local_authorities.csv

@ -0,0 +1,5 @@
code,name,start_year,end_year
E08000016,Barnsley,2021,2025
E08000019,Sheffield,2021,2025
E08000038,Barnsley,2025,
E08000039,Sheffield,2025,
1 code name start_year end_year
2 E08000016 Barnsley 2021 2025
3 E08000019 Sheffield 2021 2025
4 E08000038 Barnsley 2025
5 E08000039 Sheffield 2025

5
config/local_authorities_data/local_authority_links_2025.csv

@ -0,0 +1,5 @@
local_authority_code,linked_local_authority_code
E08000038,E08000016
E08000039,E08000019
E08000016,E08000038
E08000019,E08000039
1 local_authority_code linked_local_authority_code
2 E08000038 E08000016
3 E08000039 E08000019
4 E08000016 E08000038
5 E08000019 E08000039

8
config/locales/forms/2025/lettings/soft_validations.en.yml

@ -130,3 +130,11 @@ en:
question_text: "Are you sure the property has been vacant for this long?"
title_text: "You told us the property has been vacant for 2 years."
informative_text: "This is longer than we would expect."
no_address_found:
page_header: ""
check_answer_label: "No address found"
hint_text: ""
question_text: "We could not find an address that matches your search. You can search again or continue to enter the address manually."
title_text: "No address found"
informative_text: "We could not find an address that matches your search. You can search again or continue to enter the address manually."

16
db/seeds.rb

@ -13,9 +13,11 @@ def find_or_create_user(organisation, email, name, role)
end
if LocalAuthority.count.zero?
la_path = "config/local_authorities_data/initial_local_authorities.csv"
service = Imports::LocalAuthoritiesService.new(path: la_path)
service.call
paths = ["config/local_authorities_data/initial_local_authorities.csv", "config/local_authorities_data/2025_local_authorities.csv"]
paths.each do |path|
service = Imports::LocalAuthoritiesService.new(path:)
service.call
end
end
unless Rails.env.test?
@ -175,7 +177,9 @@ unless Rails.env.test?
end
if LocalAuthority.count.zero?
path = "config/local_authorities_data/initial_local_authorities.csv"
service = Imports::LocalAuthoritiesService.new(path:)
service.call
paths = ["config/local_authorities_data/initial_local_authorities.csv", "config/local_authorities_data/2025_local_authorities.csv"]
paths.each do |path|
service = Imports::LocalAuthoritiesService.new(path:)
service.call
end
end

23
spec/helpers/locations_helper_spec.rb

@ -368,4 +368,27 @@ RSpec.describe LocationsHelper do
end
end
end
describe "formatted_local_authority_timeline" do
before do
LocalAuthorityLink.create!(local_authority_id: LocalAuthority.find_by(code: "E07000030").id, linked_local_authority_id: LocalAuthority.find_by(code: "E06000063").id)
LocalAuthorityLink.create!(local_authority_id: LocalAuthority.find_by(code: "E08000016").id, linked_local_authority_id: LocalAuthority.find_by(code: "E08000038").id)
end
context "when the location LA's have changed" do
let(:location) { FactoryBot.create(:location, location_code: "E07000030") }
it "displays a timeline of LAs" do
expect(formatted_local_authority_timeline(location)).to eq("Eden (until 31 March 2023)\nCumberland (1 April 2023 - present)")
end
end
context "when the LA name hasn't changed but Ecode has changed" do
let(:location) { FactoryBot.create(:location, location_code: "E08000016") }
it "only displays the location name once" do
expect(formatted_local_authority_timeline(location)).to eq("Barnsley")
end
end
end
end

120
spec/models/sales_log_spec.rb

@ -571,7 +571,7 @@ RSpec.describe SalesLog, type: :model do
before do
WebMock.stub_request(:get, /api\.postcodes\.io\/postcodes\/CA101AA/)
.to_return(status: 200, body: '{"status":200,"result":{"admin_district":"Eden","codes":{"admin_district":"E07000030"}}}', headers: {})
.to_return(status: 200, body: '{"status":200,"result":{"admin_district":"Eden","codes":{"admin_district":"E06000064"}}}', headers: {})
end
it "sets previous postcode for discounted sale" do
@ -610,6 +610,124 @@ RSpec.describe SalesLog, type: :model do
end
end
context "when saving address with LAs that have changed E-codes (LA inferred from postcode)" do
context "when LA is inferred from postcode" do
let(:address_sales_log_24_25) do
create(:sales_log, :shared_ownership_setup_complete, uprn_known: 0, uprn: nil, postcode_full: "CA10 1AA", saledate: Time.zone.local(2024, 5, 2))
end
let(:address_sales_log_25_26) do
create(:sales_log, :shared_ownership_setup_complete, postcode_full: "CA10 1AA", saledate: Time.zone.local(2025, 5, 2))
end
before do
Timecop.freeze(Time.zone.local(2025, 5, 10))
Singleton.__init__(FormHandler)
end
after do
Timecop.return
end
context "when old(2024) E-code gets returned" do
before do
WebMock.stub_request(:get, /api\.postcodes\.io\/postcodes\/CA101AA/)
.to_return(status: 200, body: '{"status":200,"result":{"admin_district":"Barnsley","codes":{"admin_district":"E08000016"}}}', headers: {})
end
context "with 2024 log" do
it "keeps 2024 E-code" do
expect(address_sales_log_24_25.la).to eq("E08000016")
end
end
context "with 2025 log" do
it "uses new 2025 E-code if" do
expect(address_sales_log_25_26.la).to eq("E08000038")
end
end
end
context "when new(2025) E-code gets returned" do
before do
WebMock.stub_request(:get, /api\.postcodes\.io\/postcodes\/CA101AA/)
.to_return(status: 200, body: '{"status":200,"result":{"admin_district":"Barnsley","codes":{"admin_district":"E08000038"}}}', headers: {})
end
context "with 2024 log" do
it "uses 2024 E-code" do
expect(address_sales_log_24_25.la).to eq("E08000016")
end
end
context "with 2025 log" do
it "keeps 2025 E-code if new(2025) E-code gets returned" do
expect(address_sales_log_25_26.la).to eq("E08000038")
end
end
end
end
end
context "when saving address with LAs that have changed E-codes" do
context "when address inferred from uprn - we still get LA from postcode" do
let(:address_sales_log_24_25) do
create(:sales_log, :shared_ownership_setup_complete, uprn_known: 1, uprn: 1, saledate: Time.zone.local(2024, 5, 2))
end
let(:address_sales_log_25_26) do
create(:sales_log, :shared_ownership_setup_complete, uprn_known: 1, uprn: 1, saledate: Time.zone.local(2025, 5, 2))
end
before do
Timecop.freeze(Time.zone.local(2025, 5, 10))
Singleton.__init__(FormHandler)
end
after do
Timecop.return
end
context "when old(2024) E-code gets returned" do
before do
WebMock.stub_request(:get, /api\.postcodes\.io\/postcodes\/AA11AA/)
.to_return(status: 200, body: '{"status":200,"result":{"admin_district":"Barnsley","codes":{"admin_district":"E08000016"}}}', headers: {})
end
context "with 2024 log" do
it "keeps 2024 E-code" do
expect(address_sales_log_24_25.la).to eq("E08000016")
end
end
context "with 2025 log" do
it "uses new 2025 E-code if" do
expect(address_sales_log_25_26.la).to eq("E08000038")
end
end
end
context "when new(2025) E-code gets returned" do
before do
WebMock.stub_request(:get, /api\.postcodes\.io\/postcodes\/AA11AA/)
.to_return(status: 200, body: '{"status":200,"result":{"admin_district":"Barnsley","codes":{"admin_district":"E08000038"}}}', headers: {})
end
context "with 2024 log" do
it "uses 2024 E-code" do # currently returns nil
expect(address_sales_log_24_25.la).to eq("E08000016")
end
end
context "with 2025 log" do
it "keeps 2025 E-code if new(2025) E-code gets returned" do
expect(address_sales_log_25_26.la).to eq("E08000038")
end
end
end
end
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")}/)

Loading…
Cancel
Save