diff --git a/app/controllers/organisations_controller.rb b/app/controllers/organisations_controller.rb index a6d9fb61e..ea0b154e5 100644 --- a/app/controllers/organisations_controller.rb +++ b/app/controllers/organisations_controller.rb @@ -176,7 +176,7 @@ class OrganisationsController < ApplicationController end def lettings_logs - organisation_logs = LettingsLog.visible.filter_by_organisation(@organisation).filter_by_years_or_nil(FormHandler.instance.years_of_available_lettings_forms) + organisation_logs = LettingsLog.visible.filter_by_organisation(@organisation.absorbed_organisations + [@organisation]).filter_by_years_or_nil(FormHandler.instance.years_of_available_lettings_forms) unpaginated_filtered_logs = filter_manager.filtered_logs(organisation_logs, search_term, session_filters) @search_term = search_term @@ -206,7 +206,7 @@ class OrganisationsController < ApplicationController end def sales_logs - organisation_logs = SalesLog.visible.filter_by_organisation(@organisation).filter_by_years_or_nil(FormHandler.instance.years_of_available_sales_forms) + organisation_logs = SalesLog.visible.filter_by_organisation(@organisation.absorbed_organisations + [@organisation]).filter_by_years_or_nil(FormHandler.instance.years_of_available_sales_forms) unpaginated_filtered_logs = filter_manager.filtered_logs(organisation_logs, search_term, session_filters) respond_to do |format| diff --git a/app/helpers/locations_helper.rb b/app/helpers/locations_helper.rb index 0500902f0..9ef74ca51 100644 --- a/app/helpers/locations_helper.rb +++ b/app/helpers/locations_helper.rb @@ -179,7 +179,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)} -" diff --git a/app/models/form/lettings/questions/previous_tenure.rb b/app/models/form/lettings/questions/previous_tenure.rb index 360f1960a..73585c412 100644 --- a/app/models/form/lettings/questions/previous_tenure.rb +++ b/app/models/form/lettings/questions/previous_tenure.rb @@ -5,7 +5,7 @@ class Form::Lettings::Questions::PreviousTenure < ::Form::Question @copy_key = "lettings.household_situation.prevten.not_renewal" @type = "radio" @check_answers_card_number = 0 - @answer_options = ANSWER_OPTIONS + @answer_options = form.start_year_2025_or_later? ? ANSWER_OPTIONS_2025 : ANSWER_OPTIONS @question_number = QUESTION_NUMBER_FROM_YEAR[form.start_date.year] || QUESTION_NUMBER_FROM_YEAR[QUESTION_NUMBER_FROM_YEAR.keys.max] end @@ -38,5 +38,35 @@ class Form::Lettings::Questions::PreviousTenure < ::Form::Question "25" => { "value" => "Any other accommodation" }, }.freeze + ANSWER_OPTIONS_2025 = { + "30" => { "value" => "Fixed-term local authority general needs tenancy" }, + "32" => { "value" => "Fixed-term private registered provider (PRP) general needs tenancy" }, + "31" => { "value" => "Lifetime local authority general needs tenancy" }, + "33" => { "value" => "Lifetime private registered provider (PRP) general needs tenancy" }, + "34" => { "value" => "Specialist retirement housing" }, + "36" => { "value" => "Sheltered housing for adults aged under 55 years" }, + "35" => { "value" => "Extra care housing" }, + "6" => { "value" => "Other supported housing" }, + "3" => { "value" => "Private sector tenancy" }, + "27" => { "value" => "Owner occupation (low-cost home ownership)" }, + "26" => { "value" => "Owner occupation (private)" }, + "28" => { "value" => "Living with friends and family (long-term)" }, + "38" => { "value" => "Sofa surfing (moving regularly between family and friends, no permanent bed)" }, + "14" => { "value" => "Bed and breakfast" }, + "7" => { "value" => "Direct access hostel" }, + "10" => { "value" => "Hospital" }, + "29" => { "value" => "Prison or approved probation hostel" }, + "19" => { "value" => "Rough sleeping" }, + "18" => { "value" => "Any other temporary accommodation" }, + "13" => { "value" => "Children’s home or foster care" }, + "24" => { "value" => "Home Office Asylum Support" }, + "37" => { "value" => "Host family or similar refugee accommodation" }, + "23" => { "value" => "Mobile home or caravan" }, + "21" => { "value" => "Refuge" }, + "9" => { "value" => "Residential care home" }, + "4" => { "value" => "Tied housing or rented with job" }, + "25" => { "value" => "Any other accommodation" }, + }.freeze + QUESTION_NUMBER_FROM_YEAR = { 2023 => 78, 2024 => 77 }.freeze end diff --git a/app/models/form/sales/questions/ownership_scheme.rb b/app/models/form/sales/questions/ownership_scheme.rb index 5eacb8f26..09d96c2fe 100644 --- a/app/models/form/sales/questions/ownership_scheme.rb +++ b/app/models/form/sales/questions/ownership_scheme.rb @@ -9,8 +9,8 @@ class Form::Sales::Questions::OwnershipScheme < ::Form::Question def answer_options if form.start_year_2025_or_later? { - "1" => { "value" => "Yes - a shared ownership scheme", "hint" => "When the purchaser buys an initial share of up to 75% of the property value and pays rent to the Private Registered Provider (PRP) on the remaining portion, or a subsequent staircasing transaction" }, - "2" => { "value" => "Yes - a discounted ownership scheme" }, + "1" => { "value" => "Shared Ownership", "hint" => "When the purchaser buys an initial share of up to 75% of the property value and pays rent to the Private Registered Provider (PRP) on the remaining portion, or a subsequent staircasing transaction" }, + "2" => { "value" => "Discounted Ownership" }, }.freeze elsif form.start_year_2024_or_later? { diff --git a/app/models/log.rb b/app/models/log.rb index 94f0ff58d..66e996892 100644 --- a/app/models/log.rb +++ b/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 diff --git a/config/local_authorities_data/2025_local_authorities.csv b/config/local_authorities_data/2025_local_authorities.csv new file mode 100644 index 000000000..ac5f2e319 --- /dev/null +++ b/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, diff --git a/config/local_authorities_data/local_authority_links_2025.csv b/config/local_authorities_data/local_authority_links_2025.csv new file mode 100644 index 000000000..be2eb290a --- /dev/null +++ b/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 \ No newline at end of file diff --git a/config/locales/forms/2025/lettings/soft_validations.en.yml b/config/locales/forms/2025/lettings/soft_validations.en.yml index 65530970f..8e018b315 100644 --- a/config/locales/forms/2025/lettings/soft_validations.en.yml +++ b/config/locales/forms/2025/lettings/soft_validations.en.yml @@ -146,3 +146,12 @@ 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" + check_answer_prompt: "Confirm 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." diff --git a/config/locales/forms/2025/sales/sale_information.en.yml b/config/locales/forms/2025/sales/sale_information.en.yml index 633791404..8e25f4b65 100644 --- a/config/locales/forms/2025/sales/sale_information.en.yml +++ b/config/locales/forms/2025/sales/sale_information.en.yml @@ -52,13 +52,13 @@ en: page_header: "" check_answer_label: "Part of a back-to-back staircasing transaction" check_answer_prompt: "" - hint_text: "" + hint_text: "Back-to-back staircasing transactions are used as a way for shared owners who own less than 100% of their property to sell on the open market. It involves the shared owner purchasing the remaining share from their landlord and immediately selling 100% of the property to a buyer on the open market. The landlord is then reimbursed for the staircasing transaction through the proceeds of sale to the buyer." question_text: "Is this transaction part of a back-to-back staircasing transaction to facilitate sale of the home on the open market?" firststair: page_header: "" check_answer_label: "First time staircasing" - check_answer_prompt: "" + check_answer_prompt: "Tell us if this is the first time staircasing" hint_text: "" question_text: "Is this the first time the shared owner has engaged in staircasing in the home?" @@ -66,24 +66,24 @@ en: page_header: "About previous staircasing transactions" numstair: check_answer_label: "Number of staircasing transactions" - check_answer_prompt: "" + check_answer_prompt: "Enter number of staircasing transaction" hint_text: "" question_text: "Including this time, how many times has the shared owner engaged in staircasing in the home?" initialpurchase: check_answer_label: "Initial staircasing transaction" - check_answer_prompt: "" + check_answer_prompt: "Enter initial staircasing transaction date" hint_text: "" question_text: "What was the date of the initial purchase of a share in the property?" lasttransaction: check_answer_label: "Last staircasing transaction" - check_answer_prompt: "" + check_answer_prompt: "Enter last staircasing transaction date" hint_text: "" question_text: "What was the date of the last staircasing transaction?" resale: page_header: "" - check_answer_label: "Is this a resale?" - check_answer_prompt: "" + check_answer_label: "Resale" + check_answer_prompt: "Tell us if this is a resale" hint_text: "If the social landlord has previously sold the property to another buyer and is now reselling the property, select 'yes'. If this is the first time the property has been sold, select 'no'." question_text: "Is this a resale?" @@ -111,14 +111,14 @@ en: soctenant: joint_purchase: page_header: "" - check_answer_label: "Any buyers were registered providers, housing association or local authority tenants immediately before this sale?" - check_answer_prompt: "" + check_answer_label: "Buyers were registered providers, housing association or local authority tenants immediately before this sale" + check_answer_prompt: "Tell us if buyers were registered providers, housing association or local authority tenants" hint_text: "" question_text: "Were any of the buyers private registered providers, housing association or local authority tenants immediately before this sale?" not_joint_purchase: page_header: "" check_answer_label: "Buyer was a registered provider, housing association or local authority tenant immediately before this sale?" - check_answer_prompt: "" + check_answer_prompt: "Tell us if buyer was a registered provider, housing association or local authority tenant" hint_text: "" question_text: "Was the buyer a private registered provider, housing association or local authority tenant immediately before this sale?" diff --git a/db/seeds.rb b/db/seeds.rb index f3dcb688d..d3e7beb3f 100644 --- a/db/seeds.rb +++ b/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 diff --git a/spec/helpers/locations_helper_spec.rb b/spec/helpers/locations_helper_spec.rb index 5b3a77e61..0a8eed96f 100644 --- a/spec/helpers/locations_helper_spec.rb +++ b/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 diff --git a/spec/models/form/lettings/pages/previous_housing_situation_spec.rb b/spec/models/form/lettings/pages/previous_housing_situation_spec.rb index 9c86a5827..907c8671e 100644 --- a/spec/models/form/lettings/pages/previous_housing_situation_spec.rb +++ b/spec/models/form/lettings/pages/previous_housing_situation_spec.rb @@ -3,7 +3,7 @@ require "rails_helper" RSpec.describe Form::Lettings::Pages::PreviousHousingSituation, type: :model do subject(:page) { described_class.new(nil, nil, subsection) } - let(:subsection) { instance_double(Form::Subsection, form: instance_double(Form, start_date: Time.zone.local(2024, 4, 1))) } + let(:subsection) { instance_double(Form::Subsection, form: instance_double(Form, start_date: Time.zone.local(2024, 4, 1), start_year_2025_or_later?: false)) } it "has correct subsection" do expect(page.subsection).to eq(subsection) diff --git a/spec/models/form/lettings/questions/previous_tenure_spec.rb b/spec/models/form/lettings/questions/previous_tenure_spec.rb index 2b8dcc338..d5eaae5fe 100644 --- a/spec/models/form/lettings/questions/previous_tenure_spec.rb +++ b/spec/models/form/lettings/questions/previous_tenure_spec.rb @@ -3,7 +3,8 @@ require "rails_helper" RSpec.describe Form::Lettings::Questions::PreviousTenure, type: :model do subject(:question) { described_class.new(nil, nil, page) } - let(:page) { instance_double(Form::Page, subsection: instance_double(Form::Subsection, form: instance_double(Form, start_date: Time.zone.local(2023, 4, 1)))) } + let(:form) { instance_double(Form, start_date: Time.zone.local(2023, 4, 1), start_year_2025_or_later?: false) } + let(:page) { instance_double(Form::Page, subsection: instance_double(Form::Subsection, form:)) } it "has the correct id" do expect(question.id).to eq("prevten") @@ -51,4 +52,40 @@ RSpec.describe Form::Lettings::Questions::PreviousTenure, type: :model do "25" => { "value" => "Any other accommodation" }, }) end + + context "with 2025 logs" do + let(:form) { instance_double(Form, start_date: Time.zone.local(2025, 4, 1), start_year_2025_or_later?: true) } + + it "has the correct answer_options" do + expect(question.answer_options).to eq({ + "30" => { "value" => "Fixed-term local authority general needs tenancy" }, + "32" => { "value" => "Fixed-term private registered provider (PRP) general needs tenancy" }, + "31" => { "value" => "Lifetime local authority general needs tenancy" }, + "33" => { "value" => "Lifetime private registered provider (PRP) general needs tenancy" }, + "34" => { "value" => "Specialist retirement housing" }, + "35" => { "value" => "Extra care housing" }, + "6" => { "value" => "Other supported housing" }, + "3" => { "value" => "Private sector tenancy" }, + "27" => { "value" => "Owner occupation (low-cost home ownership)" }, + "26" => { "value" => "Owner occupation (private)" }, + "28" => { "value" => "Living with friends and family (long-term)" }, + "38" => { "value" => "Sofa surfing (moving regularly between family and friends, no permanent bed)" }, + "14" => { "value" => "Bed and breakfast" }, + "7" => { "value" => "Direct access hostel" }, + "10" => { "value" => "Hospital" }, + "29" => { "value" => "Prison or approved probation hostel" }, + "19" => { "value" => "Rough sleeping" }, + "18" => { "value" => "Any other temporary accommodation" }, + "13" => { "value" => "Children’s home or foster care" }, + "24" => { "value" => "Home Office Asylum Support" }, + "23" => { "value" => "Mobile home or caravan" }, + "21" => { "value" => "Refuge" }, + "9" => { "value" => "Residential care home" }, + "4" => { "value" => "Tied housing or rented with job" }, + "36" => { "value" => "Sheltered housing for adults aged under 55 years" }, + "37" => { "value" => "Host family or similar refugee accommodation" }, + "25" => { "value" => "Any other accommodation" }, + }) + end + end end diff --git a/spec/models/form/sales/questions/ownership_scheme_spec.rb b/spec/models/form/sales/questions/ownership_scheme_spec.rb index 647de9621..656adc0e5 100644 --- a/spec/models/form/sales/questions/ownership_scheme_spec.rb +++ b/spec/models/form/sales/questions/ownership_scheme_spec.rb @@ -62,8 +62,8 @@ RSpec.describe Form::Sales::Questions::OwnershipScheme, type: :model do it "has the correct answer_options" do expect(question.answer_options).to eq({ - "1" => { "value" => "Yes - a shared ownership scheme", "hint" => "When the purchaser buys an initial share of up to 75% of the property value and pays rent to the Private Registered Provider (PRP) on the remaining portion, or a subsequent staircasing transaction" }, - "2" => { "value" => "Yes - a discounted ownership scheme" }, + "1" => { "value" => "Shared Ownership", "hint" => "When the purchaser buys an initial share of up to 75% of the property value and pays rent to the Private Registered Provider (PRP) on the remaining portion, or a subsequent staircasing transaction" }, + "2" => { "value" => "Discounted Ownership" }, }) end end diff --git a/spec/models/sales_log_spec.rb b/spec/models/sales_log_spec.rb index 3e6d6405d..70ac5455f 100644 --- a/spec/models/sales_log_spec.rb +++ b/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")}/) diff --git a/spec/requests/organisations_controller_spec.rb b/spec/requests/organisations_controller_spec.rb index 0a5614be3..f9254b048 100644 --- a/spec/requests/organisations_controller_spec.rb +++ b/spec/requests/organisations_controller_spec.rb @@ -1307,6 +1307,37 @@ RSpec.describe OrganisationsController, type: :request do end end end + + context "when the organisation has absorbed another organisation" do + let(:absorbed_organisation) { create(:organisation) } + let(:number_of_absorbed_org_lettings_logs) { 3 } + let(:lettings_log) { create(:lettings_log, owning_organisation: absorbed_organisation) } + + before do + organisation.update!(absorbed_organisations: [absorbed_organisation]) + create_list(:lettings_log, number_of_absorbed_org_lettings_logs, owning_organisation: absorbed_organisation) + end + + context "without search query" do + before do + get "/organisations/#{organisation.id}/lettings-logs", headers:, params: {} + end + + it "returns a count of all logs for both the merging and absorbed organisations" do + expect(page).to have_content("#{total_number_of_org1_logs + number_of_absorbed_org_lettings_logs} total logs") + end + end + + context "when searching for an absorbing organisation by ID" do + before do + get "/organisations/#{organisation.id}/lettings-logs?search=#{lettings_log.id}", headers:, params: {} + end + + it "displays the lettings log from the absorbed organisation" do + expect(page).to have_content(lettings_log.id) + end + end + end end context "when viewing a specific organisation's sales logs" do @@ -1398,6 +1429,37 @@ RSpec.describe OrganisationsController, type: :request do end end end + + context "when the organisation has absorbed another organisation" do + let(:absorbed_organisation) { create(:organisation) } + let(:number_of_absorbed_org_sales_logs) { 3 } + let(:sales_log) { create(:sales_log, owning_organisation: absorbed_organisation) } + + before do + organisation.update!(absorbed_organisations: [absorbed_organisation]) + create_list(:sales_log, number_of_absorbed_org_sales_logs, owning_organisation: absorbed_organisation) + end + + context "without search query" do + before do + get "/organisations/#{organisation.id}/sales-logs", headers:, params: {} + end + + it "returns a count of all logs for both the merging and absorbed organisations" do + expect(page).to have_content("#{number_of_org1_sales_logs + number_of_absorbed_org_sales_logs} total logs") + end + end + + context "when searching for an absorbing organisation by ID" do + before do + get "/organisations/#{organisation.id}/sales-logs?search=#{sales_log.id}", headers:, params: {} + end + + it "displays the sales log from the absorbed organisation" do + expect(page).to have_content(sales_log.id) + end + end + end end context "when viewing a specific organisation's users" do