Browse Source

Merge branch 'main' into CLDC-3829-add-guidance-link-to-log-pages

pull/2940/head
kosiakkatrina 2 months ago committed by GitHub
parent
commit
ffbc32f4ce
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
  1. 1
      .env.example
  2. 2
      .ruby-version
  3. 6
      Dockerfile
  4. 2
      Gemfile
  5. 30
      Gemfile.lock
  6. 6
      app/components/bulk_upload_error_row_component.html.erb
  7. 2
      app/components/bulk_upload_summary_component.html.erb
  8. 6
      app/controllers/form_controller.rb
  9. 2
      app/helpers/tag_helper.rb
  10. 2
      app/mailers/bulk_upload_mailer.rb
  11. 1
      app/models/bulk_upload_error.rb
  12. 15
      app/models/derived_variables/lettings_log_variables.rb
  13. 3
      app/models/form/lettings/pages/address_fallback.rb
  14. 2
      app/models/form/lettings/questions/address_line1.rb
  15. 2
      app/models/form/lettings/questions/brent_4_weekly.rb
  16. 2
      app/models/form/lettings/questions/brent_bi_weekly.rb
  17. 2
      app/models/form/lettings/questions/brent_monthly.rb
  18. 2
      app/models/form/lettings/questions/brent_weekly.rb
  19. 2
      app/models/form/lettings/questions/county.rb
  20. 2
      app/models/form/lettings/questions/first_time_property_let_as_social_housing.rb
  21. 2
      app/models/form/lettings/questions/hbrentshortfall.rb
  22. 2
      app/models/form/lettings/questions/joint.rb
  23. 2
      app/models/form/lettings/questions/la.rb
  24. 2
      app/models/form/lettings/questions/postcode_for_full_address.rb
  25. 2
      app/models/form/lettings/questions/previous_let_type.rb
  26. 5
      app/models/form/lettings/questions/previous_tenure.rb
  27. 8
      app/models/form/lettings/questions/previous_tenure_renewal.rb
  28. 2
      app/models/form/lettings/questions/pscharge_4_weekly.rb
  29. 2
      app/models/form/lettings/questions/pscharge_bi_weekly.rb
  30. 2
      app/models/form/lettings/questions/pscharge_monthly.rb
  31. 2
      app/models/form/lettings/questions/pscharge_weekly.rb
  32. 2
      app/models/form/lettings/questions/rsnvac.rb
  33. 2
      app/models/form/lettings/questions/rsnvac_first_let.rb
  34. 2
      app/models/form/lettings/questions/scharge_4_weekly.rb
  35. 2
      app/models/form/lettings/questions/scharge_bi_weekly.rb
  36. 2
      app/models/form/lettings/questions/scharge_monthly.rb
  37. 2
      app/models/form/lettings/questions/scharge_weekly.rb
  38. 10
      app/models/form/lettings/questions/sheltered.rb
  39. 2
      app/models/form/lettings/questions/starter_tenancy_type.rb
  40. 2
      app/models/form/lettings/questions/startertenancy.rb
  41. 2
      app/models/form/lettings/questions/supcharg_4_weekly.rb
  42. 2
      app/models/form/lettings/questions/supcharg_bi_weekly.rb
  43. 2
      app/models/form/lettings/questions/supcharg_monthly.rb
  44. 2
      app/models/form/lettings/questions/supcharg_weekly.rb
  45. 2
      app/models/form/lettings/questions/tenancy_length.rb
  46. 2
      app/models/form/lettings/questions/tenancy_length_affordable_rent.rb
  47. 2
      app/models/form/lettings/questions/tenancy_length_intermediate_rent.rb
  48. 2
      app/models/form/lettings/questions/tenancy_length_periodic.rb
  49. 2
      app/models/form/lettings/questions/tenancy_other.rb
  50. 2
      app/models/form/lettings/questions/tenancy_type.rb
  51. 2
      app/models/form/lettings/questions/town_or_city.rb
  52. 2
      app/models/form/lettings/questions/tshortfall.rb
  53. 2
      app/models/form/lettings/questions/tshortfall_known.rb
  54. 2
      app/models/form/lettings/questions/uprn.rb
  55. 2
      app/models/form/lettings/questions/uprn_known.rb
  56. 3
      app/models/form/page.rb
  57. 3
      app/models/form/sales/pages/address_fallback.rb
  58. 3
      app/views/bulk_upload_lettings_results/show.html.erb
  59. 3
      app/views/bulk_upload_sales_results/show.html.erb
  60. 2
      app/views/csv_downloads/show.html.erb
  61. 2
      app/views/form/page.html.erb
  62. 2
      config/locales/forms/2024/lettings/property_information.en.yml
  63. 2
      config/locales/forms/2024/sales/property_information.en.yml
  64. 10
      config/locales/forms/2025/lettings/property_information.en.yml
  65. 2
      config/locales/forms/2025/sales/property_information.en.yml
  66. 4
      config/locales/forms/2025/sales/setup.en.yml
  67. 2
      config/locales/validations/lettings/2024/bulk_upload.en.yml
  68. 4
      db/migrate/20211126142105_user_case_logs_belong_to_organisation.rb
  69. 2
      db/migrate/20220323094418_create_data_protection_confirmation.rb
  70. 2
      db/migrate/20220427160536_add_created_by_to_case_logs.rb
  71. 6
      db/migrate/20220826093411_add_sales_log.rb
  72. 4
      db/migrate/20221207141947_add_updated_by_to_logs.rb
  73. 2
      db/migrate/20230530094653_add_data_sharing_agreement.rb
  74. 2
      db/migrate/20231121131725_add_sales_managing_organisation.rb
  75. 4
      db/migrate/20240408102550_add_created_by.rb
  76. 10
      db/schema.rb
  77. 10
      docs/Gemfile.lock
  78. 4
      docs/setup.md
  79. 20
      lib/tasks/correct_checkbox_values.rake
  80. 2
      spec/components/bulk_upload_error_row_component_spec.rb
  81. 4
      spec/components/bulk_upload_summary_component_spec.rb
  82. 24
      spec/features/sales_log_spec.rb
  83. 2
      spec/fixtures/files/lettings_log_csv_export_codes_23.csv
  84. 2
      spec/fixtures/files/lettings_log_csv_export_codes_24.csv
  85. 2
      spec/fixtures/files/lettings_log_csv_export_labels_23.csv
  86. 2
      spec/fixtures/files/lettings_log_csv_export_labels_24.csv
  87. 2
      spec/fixtures/files/lettings_log_csv_export_non_support_codes_23.csv
  88. 2
      spec/fixtures/files/lettings_log_csv_export_non_support_codes_24.csv
  89. 2
      spec/fixtures/files/lettings_log_csv_export_non_support_labels_23.csv
  90. 2
      spec/fixtures/files/lettings_log_csv_export_non_support_labels_24.csv
  91. 216
      spec/lib/tasks/correct_checkbox_values_spec.rb
  92. 2
      spec/mailers/bulk_upload_mailer_spec.rb
  93. 2
      spec/models/form/lettings/pages/previous_housing_situation_renewal_spec.rb
  94. 18
      spec/models/form/lettings/questions/first_time_property_let_as_social_housing_spec.rb
  95. 24
      spec/models/form/lettings/questions/joint_spec.rb
  96. 24
      spec/models/form/lettings/questions/la_spec.rb
  97. 12
      spec/models/form/lettings/questions/previous_let_type_spec.rb
  98. 31
      spec/models/form/lettings/questions/previous_tenure_renewal_spec.rb
  99. 65
      spec/models/form/lettings/questions/previous_tenure_spec.rb
  100. 22
      spec/models/form/lettings/questions/rsnvac_spec.rb
  101. Some files were not shown because too many files have changed in this diff Show More

1
.env.example

@ -1,5 +1,6 @@
DB_USERNAME=postgres-user
DB_PASSWORD=postgres-password
DB_HOST=localhost
GOVUK_NOTIFY_API_KEY=<notify-key-here-if-testing-emails-or-admin-users>
OTP_SECRET_ENCRYPTION_KEY="<Generate this using bundle exec rake secret>"

2
.ruby-version

@ -1 +1 @@
3.1.4
3.1.6

6
Dockerfile

@ -1,4 +1,4 @@
FROM ruby:3.1.4-alpine3.18 as base
FROM ruby:3.1.6-alpine3.20 as base
WORKDIR /app
@ -10,10 +10,10 @@ RUN apk add --update --no-cache tzdata && \
# build-base: compilation tools for bundle
# yarn: node package manager
# postgresql-dev: postgres driver and libraries
RUN apk add --no-cache build-base=0.5-r3 busybox=1.36.1-r7 nodejs-current=20.8.1-r0 yarn=1.22.19-r0 postgresql13-dev=13.18-r0 bash=5.2.15-r5
RUN apk add --no-cache build-base=0.5-r3 busybox=1.36.1-r29 nodejs=20.15.1-r0 yarn=1.22.22-r0 bash=5.2.26-r0 libpq-dev
# Bundler version should be the same version as what the Gemfile.lock was bundled with
RUN gem install bundler:2.3.14 --no-document
RUN gem install bundler:2.6.4 --no-document
COPY .ruby-version Gemfile Gemfile.lock /app/
RUN bundle config set without "development test"

2
Gemfile

@ -3,7 +3,7 @@
source "https://rubygems.org"
git_source(:github) { |repo| "https://github.com/#{repo}.git" }
ruby "3.1.4"
ruby "3.1.6"
# Bundle edge Rails instead: gem 'rails', github: 'rails/rails', branch: 'main'
gem "rails", "~> 7.2.2"

30
Gemfile.lock

@ -278,7 +278,7 @@ GEM
nested_form (0.3.2)
net-http (0.4.1)
uri
net-imap (0.5.1)
net-imap (0.5.6)
date
net-protocol
net-pop (0.1.2)
@ -288,11 +288,13 @@ GEM
net-smtp (0.5.0)
net-protocol
nio4r (2.7.4)
nokogiri (1.17.1-arm64-darwin)
nokogiri (1.18.3-arm64-darwin)
racc (~> 1.4)
nokogiri (1.17.1-x86_64-darwin)
nokogiri (1.18.3-x86_64-darwin)
racc (~> 1.4)
nokogiri (1.17.1-x86_64-linux)
nokogiri (1.18.3-x86_64-linux-gnu)
racc (~> 1.4)
nokogiri (1.18.3-x86_64-linux-musl)
racc (~> 1.4)
notifications-ruby-client (6.0.0)
jwt (>= 1.5, < 3)
@ -337,7 +339,7 @@ GEM
activesupport (>= 3.0.0)
raabro (1.4.0)
racc (1.8.1)
rack (3.1.8)
rack (3.1.10)
rack-attack (6.7.0)
rack (>= 1.0, < 4)
rack-mini-profiler (3.3.1)
@ -494,7 +496,7 @@ GEM
thor (1.3.2)
thread_safe (0.3.6)
timecop (0.9.8)
timeout (0.4.2)
timeout (0.4.3)
turbo-rails (2.0.11)
actionpack (>= 6.0.0)
railties (>= 6.0.0)
@ -534,14 +536,10 @@ GEM
zeitwerk (2.6.18)
PLATFORMS
arm64-darwin-21
arm64-darwin-22
arm64-darwin-23
x86_64-darwin-19
x86_64-darwin-20
x86_64-darwin-21
x86_64-darwin-22
x86_64-linux
arm64-darwin
x86_64-darwin
x86_64-linux-gnu
x86_64-linux-musl
DEPENDENCIES
auto_strip_attributes
@ -608,7 +606,7 @@ DEPENDENCIES
webmock
RUBY VERSION
ruby 3.1.4p223
ruby 3.1.6p260
BUNDLED WITH
2.3.14
2.6.4

6
app/components/bulk_upload_error_row_component.html.erb

@ -37,14 +37,14 @@
<% end %>
<% if potential_errors.any? %>
<h2 class="govuk-heading-m">Potential errors</h2>
<p class="govuk-body">The following groups of cells might have conflicting data. Check the answers and fix any incorrect data.<br><br>If the answers are correct, fix the critical errors and upload the file again. You'll need to confirm that the following data is correct when the file only contains potential errors.</p>
<h2 class="govuk-heading-m">Confirmation needed</h2>
<p class="govuk-body">Potential data discrepancies exist in the following cells.<br><br>Please resolve all critical errors and review the cells with data discrepancies before re-uploading the file. Bulk confirmation of potential discrepancies is accessible only after all critical errors have been resolved.</p>
<%= govuk_table(html_attributes: { class: "no-bottom-border" }) do |table| %>
<%= table.with_head do |head| %>
<% head.with_row do |row| %>
<% row.with_cell(header: true, text: "Cell") %>
<% row.with_cell(header: true, text: "Question") %>
<% row.with_cell(header: true, text: "Potential error") %>
<% row.with_cell(header: true, text: "Confirmation needed") %>
<% row.with_cell(header: true, text: "Specification") %>
<% end %>
<% end %>

2
app/components/bulk_upload_summary_component.html.erb

@ -28,7 +28,7 @@
[bulk_upload.total_logs_count, "total log"],
[setup_errors_count, "error on important questions", "errors on important questions"],
[critical_errors_count, "critical error"],
[potential_errors_count, "potential error"],
[potential_errors_count, "confirmation needed", "confirmations needed"],
) %>
</div>
<% end %>

6
app/controllers/form_controller.rb

@ -155,9 +155,9 @@ private
next unless question_params
if %w[checkbox validation_override].include?(question.type)
if question.type == "checkbox"
question.answer_keys_without_dividers.each do |option|
result[option] = question_params.include?(option) ? 1 : 0
result[option] = 1 if question_params.include?(option)
end
elsif question.type != "date"
result[question.id] = question_params
@ -347,7 +347,7 @@ private
end
def question_missing_response?(responses_for_page, question)
if %w[checkbox validation_override].include?(question.type)
if question.type == "checkbox"
answered = question.answer_keys_without_dividers.map do |option|
session["fields"][option] = @log[option] = params[@log.log_type][question.id].include?(option) ? 1 : 0
params[@log.log_type][question.id].exclude?(option)

2
app/helpers/tag_helper.rb

@ -24,7 +24,7 @@ module TagHelper
processing_error: "Error processing CSV",
important_errors: "Errors on important questions in CSV",
critical_errors: "Critical errors in CSV",
potential_errors: "Potential errors in CSV",
potential_errors: "Confirmation needed in CSV",
logs_uploaded_with_errors: "Logs uploaded with errors",
errors_fixed_in_service: "Errors fixed on site",
logs_uploaded_no_errors: "Logs uploaded with no errors",

2
app/mailers/bulk_upload_mailer.rb

@ -29,7 +29,7 @@ class BulkUploadMailer < NotifyMailer
def send_check_soft_validations_mail(bulk_upload:)
title = "Check your file data"
description = "Some of your #{bulk_upload.year_combo} #{bulk_upload.log_type} data might not be right. Click the link below to review the potential errors, and check your file to see if the data is correct."
description = "We’ve identified potential discrepancies in your #{bulk_upload.year_combo} #{bulk_upload.log_type} data. Please review the flagged information via the link below and cross-reference it with your records to confirm data accuracy."
cta_link = if bulk_upload.lettings?
bulk_upload_lettings_soft_validations_check_url(bulk_upload, page: "confirm-soft-errors")
else

1
app/models/bulk_upload_error.rb

@ -6,6 +6,7 @@ class BulkUploadError < ApplicationRecord
scope :order_by_col, -> { order(Arel.sql("LPAD(col, 10, '0')")) }
scope :important, -> { where(category: "setup") }
scope :potential, -> { where(category: "soft_validation") }
scope :not_potential, -> { where.not(category: "soft_validation").or(where(category: nil)) }
scope :critical, -> { where(category: nil).or(where.not(category: %w[setup soft_validation])) }
scope :critical_or_important, -> { critical.or(important) }
end

15
app/models/derived_variables/lettings_log_variables.rb

@ -142,6 +142,8 @@ module DerivedVariables::LettingsLogVariables
end
reset_address_fields! if is_supported_housing?
set_checkbox_values!
end
private
@ -362,4 +364,17 @@ private
return 2 if rent_type == 4
return 3 if rent_type == 5
end
def set_checkbox_values!
form.questions.select { |q| q.type == "checkbox" }.each do |question|
options = question.answer_keys_without_dividers
next unless options.any? { |option| self[option] == 1 }
options.each do |option|
if self[option].nil?
self[option] = 0
end
end
end
end
end

3
app/models/form/lettings/pages/address_fallback.rb

@ -11,6 +11,7 @@ class Form::Lettings::Pages::AddressFallback < ::Form::Page
{ "is_supported_housing?" => false, "uprn_known" => 0, "address_options_present?" => false },
{ "is_supported_housing?" => false, "uprn_confirmed" => 0, "address_options_present?" => false },
]
@question_number = QUESTION_NUMBER_FROM_YEAR[form.start_date.year] || QUESTION_NUMBER_FROM_YEAR[QUESTION_NUMBER_FROM_YEAR.keys.max]
end
def questions
@ -22,4 +23,6 @@ class Form::Lettings::Pages::AddressFallback < ::Form::Page
Form::Lettings::Questions::PostcodeForFullAddress.new(nil, nil, self),
]
end
QUESTION_NUMBER_FROM_YEAR = { 2024 => 13, 2025 => 17 }.freeze
end

2
app/models/form/lettings/questions/address_line1.rb

@ -18,5 +18,5 @@ class Form::Lettings::Questions::AddressLine1 < ::Form::Question
].select(&:present?).join("\n")
end
QUESTION_NUMBER_FROM_YEAR = { 2023 => 12, 2024 => 13 }.freeze
QUESTION_NUMBER_FROM_YEAR = { 2023 => 12, 2024 => 13, 2025 => 17 }.freeze
end

2
app/models/form/lettings/questions/brent_4_weekly.rb

@ -15,5 +15,5 @@ class Form::Lettings::Questions::Brent4Weekly < ::Form::Question
@question_number = QUESTION_NUMBER_FROM_YEAR[form.start_date.year] || QUESTION_NUMBER_FROM_YEAR[QUESTION_NUMBER_FROM_YEAR.keys.max]
end
QUESTION_NUMBER_FROM_YEAR = { 2023 => 95, 2024 => 94 }.freeze
QUESTION_NUMBER_FROM_YEAR = { 2023 => 95, 2024 => 94, 2025 => 92 }.freeze
end

2
app/models/form/lettings/questions/brent_bi_weekly.rb

@ -15,5 +15,5 @@ class Form::Lettings::Questions::BrentBiWeekly < ::Form::Question
@question_number = QUESTION_NUMBER_FROM_YEAR[form.start_date.year] || QUESTION_NUMBER_FROM_YEAR[QUESTION_NUMBER_FROM_YEAR.keys.max]
end
QUESTION_NUMBER_FROM_YEAR = { 2023 => 95, 2024 => 94 }.freeze
QUESTION_NUMBER_FROM_YEAR = { 2023 => 95, 2024 => 94, 2025 => 92 }.freeze
end

2
app/models/form/lettings/questions/brent_monthly.rb

@ -15,5 +15,5 @@ class Form::Lettings::Questions::BrentMonthly < ::Form::Question
@question_number = QUESTION_NUMBER_FROM_YEAR[form.start_date.year] || QUESTION_NUMBER_FROM_YEAR[QUESTION_NUMBER_FROM_YEAR.keys.max]
end
QUESTION_NUMBER_FROM_YEAR = { 2023 => 95, 2024 => 94 }.freeze
QUESTION_NUMBER_FROM_YEAR = { 2023 => 95, 2024 => 94, 2025 => 92 }.freeze
end

2
app/models/form/lettings/questions/brent_weekly.rb

@ -15,5 +15,5 @@ class Form::Lettings::Questions::BrentWeekly < ::Form::Question
@question_number = QUESTION_NUMBER_FROM_YEAR[form.start_date.year] || QUESTION_NUMBER_FROM_YEAR[QUESTION_NUMBER_FROM_YEAR.keys.max]
end
QUESTION_NUMBER_FROM_YEAR = { 2023 => 95, 2024 => 94 }.freeze
QUESTION_NUMBER_FROM_YEAR = { 2023 => 95, 2024 => 94, 2025 => 92 }.freeze
end

2
app/models/form/lettings/questions/county.rb

@ -10,5 +10,5 @@ class Form::Lettings::Questions::County < ::Form::Question
@hide_question_number_on_page = true
end
QUESTION_NUMBER_FROM_YEAR = { 2023 => 12, 2024 => 13 }.freeze
QUESTION_NUMBER_FROM_YEAR = { 2023 => 12, 2024 => 13, 2025 => 17 }.freeze
end

2
app/models/form/lettings/questions/first_time_property_let_as_social_housing.rb

@ -22,5 +22,5 @@ class Form::Lettings::Questions::FirstTimePropertyLetAsSocialHousing < ::Form::Q
form.start_year_2024_or_later? ? "This is a re-let of existing social housing stock." : "This is a re-let of existing social housing."
end
QUESTION_NUMBER_FROM_YEAR = { 2023 => 14, 2024 => 15 }.freeze
QUESTION_NUMBER_FROM_YEAR = { 2023 => 14, 2024 => 15, 2025 => 12 }.freeze
end

2
app/models/form/lettings/questions/hbrentshortfall.rb

@ -14,5 +14,5 @@ class Form::Lettings::Questions::Hbrentshortfall < ::Form::Question
"3" => { "value" => "Don’t know" },
}.freeze
QUESTION_NUMBER_FROM_YEAR = { 2023 => 99, 2024 => 98 }.freeze
QUESTION_NUMBER_FROM_YEAR = { 2023 => 99, 2024 => 98, 2025 => 96 }.freeze
end

2
app/models/form/lettings/questions/joint.rb

@ -15,5 +15,5 @@ class Form::Lettings::Questions::Joint < ::Form::Question
"3" => { "value" => "Don’t know" },
}.freeze
QUESTION_NUMBER_FROM_YEAR = { 2023 => 25 }.freeze
QUESTION_NUMBER_FROM_YEAR = { 2023 => 25, 2024 => 25, 2025 => 26 }.freeze
end

2
app/models/form/lettings/questions/la.rb

@ -13,5 +13,5 @@ class Form::Lettings::Questions::La < ::Form::Question
{ "" => "Select an option" }.merge(LocalAuthority.active(form.start_date).england.map { |la| [la.code, la.name] }.to_h)
end
QUESTION_NUMBER_FROM_YEAR = { 2023 => 13, 2024 => 14 }.freeze
QUESTION_NUMBER_FROM_YEAR = { 2023 => 13, 2024 => 14, 2025 => 18 }.freeze
end

2
app/models/form/lettings/questions/postcode_for_full_address.rb

@ -22,5 +22,5 @@ class Form::Lettings::Questions::PostcodeForFullAddress < ::Form::Question
@hide_question_number_on_page = true
end
QUESTION_NUMBER_FROM_YEAR = { 2023 => 12, 2024 => 13 }.freeze
QUESTION_NUMBER_FROM_YEAR = { 2023 => 12, 2024 => 13, 2025 => 17 }.freeze
end

2
app/models/form/lettings/questions/previous_let_type.rb

@ -42,7 +42,7 @@ class Form::Lettings::Questions::PreviousLetType < ::Form::Question
"3" => { "value" => "Don’t know" },
}.freeze
QUESTION_NUMBER_FROM_YEAR = { 2023 => 16, 2024 => 17 }.freeze
QUESTION_NUMBER_FROM_YEAR = { 2023 => 16, 2024 => 17, 2025 => 14 }.freeze
def answer_options
return ANSWER_OPTIONS_AFTER_2025 if form.start_year_2025_or_later?

5
app/models/form/lettings/questions/previous_tenure.rb

@ -43,15 +43,14 @@ class Form::Lettings::Questions::PreviousTenure < ::Form::Question
"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" },
"38" => { "value" => "Older people’s housing for tenants with low support needs" },
"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)" },
"39" => { "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" },

8
app/models/form/lettings/questions/previous_tenure_renewal.rb

@ -5,7 +5,7 @@ class Form::Lettings::Questions::PreviousTenureRenewal < ::Form::Question
@copy_key = "lettings.household_situation.prevten.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
@ -16,5 +16,11 @@ class Form::Lettings::Questions::PreviousTenureRenewal < ::Form::Question
"6" => { "value" => "Other supported housing" },
}.freeze
ANSWER_OPTIONS_2025 = {
"35" => { "value" => "Extra care housing" },
"38" => { "value" => "Older people’s housing for tenants with low support needs" },
"6" => { "value" => "Other supported housing" },
}.freeze
QUESTION_NUMBER_FROM_YEAR = { 2023 => 78, 2024 => 77 }.freeze
end

2
app/models/form/lettings/questions/pscharge_4_weekly.rb

@ -15,5 +15,5 @@ class Form::Lettings::Questions::Pscharge4Weekly < ::Form::Question
@question_number = QUESTION_NUMBER_FROM_YEAR[form.start_date.year] || QUESTION_NUMBER_FROM_YEAR[QUESTION_NUMBER_FROM_YEAR.keys.max]
end
QUESTION_NUMBER_FROM_YEAR = { 2023 => 97, 2024 => 96 }.freeze
QUESTION_NUMBER_FROM_YEAR = { 2023 => 97, 2024 => 96, 2025 => 94 }.freeze
end

2
app/models/form/lettings/questions/pscharge_bi_weekly.rb

@ -15,5 +15,5 @@ class Form::Lettings::Questions::PschargeBiWeekly < ::Form::Question
@question_number = QUESTION_NUMBER_FROM_YEAR[form.start_date.year] || QUESTION_NUMBER_FROM_YEAR[QUESTION_NUMBER_FROM_YEAR.keys.max]
end
QUESTION_NUMBER_FROM_YEAR = { 2023 => 97, 2024 => 96 }.freeze
QUESTION_NUMBER_FROM_YEAR = { 2023 => 97, 2024 => 96, 2025 => 94 }.freeze
end

2
app/models/form/lettings/questions/pscharge_monthly.rb

@ -15,5 +15,5 @@ class Form::Lettings::Questions::PschargeMonthly < ::Form::Question
@question_number = QUESTION_NUMBER_FROM_YEAR[form.start_date.year] || QUESTION_NUMBER_FROM_YEAR[QUESTION_NUMBER_FROM_YEAR.keys.max]
end
QUESTION_NUMBER_FROM_YEAR = { 2023 => 97, 2024 => 96 }.freeze
QUESTION_NUMBER_FROM_YEAR = { 2023 => 97, 2024 => 96, 2025 => 94 }.freeze
end

2
app/models/form/lettings/questions/pscharge_weekly.rb

@ -15,5 +15,5 @@ class Form::Lettings::Questions::PschargeWeekly < ::Form::Question
@question_number = QUESTION_NUMBER_FROM_YEAR[form.start_date.year] || QUESTION_NUMBER_FROM_YEAR[QUESTION_NUMBER_FROM_YEAR.keys.max]
end
QUESTION_NUMBER_FROM_YEAR = { 2023 => 97, 2024 => 96 }.freeze
QUESTION_NUMBER_FROM_YEAR = { 2023 => 97, 2024 => 96, 2025 => 94 }.freeze
end

2
app/models/form/lettings/questions/rsnvac.rb

@ -99,5 +99,5 @@ class Form::Lettings::Questions::Rsnvac < ::Form::Question
end
end
QUESTION_NUMBER_FROM_YEAR = { 2023 => 17, 2024 => 18 }.freeze
QUESTION_NUMBER_FROM_YEAR = { 2023 => 17, 2024 => 18, 2025 => 15 }.freeze
end

2
app/models/form/lettings/questions/rsnvac_first_let.rb

@ -14,5 +14,5 @@ class Form::Lettings::Questions::RsnvacFirstLet < ::Form::Question
"15" => { "value" => "First let of new-build property" },
}.freeze
QUESTION_NUMBER_FROM_YEAR = { 2023 => 15, 2024 => 16 }.freeze
QUESTION_NUMBER_FROM_YEAR = { 2023 => 15, 2024 => 16, 2025 => 13 }.freeze
end

2
app/models/form/lettings/questions/scharge_4_weekly.rb

@ -15,5 +15,5 @@ class Form::Lettings::Questions::Scharge4Weekly < ::Form::Question
@question_number = QUESTION_NUMBER_FROM_YEAR[form.start_date.year] || QUESTION_NUMBER_FROM_YEAR[QUESTION_NUMBER_FROM_YEAR.keys.max]
end
QUESTION_NUMBER_FROM_YEAR = { 2023 => 96, 2024 => 95 }.freeze
QUESTION_NUMBER_FROM_YEAR = { 2023 => 96, 2024 => 95, 2025 => 93 }.freeze
end

2
app/models/form/lettings/questions/scharge_bi_weekly.rb

@ -15,5 +15,5 @@ class Form::Lettings::Questions::SchargeBiWeekly < ::Form::Question
@question_number = QUESTION_NUMBER_FROM_YEAR[form.start_date.year] || QUESTION_NUMBER_FROM_YEAR[QUESTION_NUMBER_FROM_YEAR.keys.max]
end
QUESTION_NUMBER_FROM_YEAR = { 2023 => 96, 2024 => 95 }.freeze
QUESTION_NUMBER_FROM_YEAR = { 2023 => 96, 2024 => 95, 2025 => 93 }.freeze
end

2
app/models/form/lettings/questions/scharge_monthly.rb

@ -15,5 +15,5 @@ class Form::Lettings::Questions::SchargeMonthly < ::Form::Question
@question_number = QUESTION_NUMBER_FROM_YEAR[form.start_date.year] || QUESTION_NUMBER_FROM_YEAR[QUESTION_NUMBER_FROM_YEAR.keys.max]
end
QUESTION_NUMBER_FROM_YEAR = { 2023 => 96, 2024 => 95 }.freeze
QUESTION_NUMBER_FROM_YEAR = { 2023 => 96, 2024 => 95, 2025 => 93 }.freeze
end

2
app/models/form/lettings/questions/scharge_weekly.rb

@ -15,5 +15,5 @@ class Form::Lettings::Questions::SchargeWeekly < ::Form::Question
@question_number = QUESTION_NUMBER_FROM_YEAR[form.start_date.year] || QUESTION_NUMBER_FROM_YEAR[QUESTION_NUMBER_FROM_YEAR.keys.max]
end
QUESTION_NUMBER_FROM_YEAR = { 2023 => 96, 2024 => 95 }.freeze
QUESTION_NUMBER_FROM_YEAR = { 2023 => 96, 2024 => 95, 2025 => 93 }.freeze
end

10
app/models/form/lettings/questions/sheltered.rb

@ -9,12 +9,14 @@ class Form::Lettings::Questions::Sheltered < ::Form::Question
def answer_options
if form.start_year_2025_or_later?
{ "1" => { "value" => "Yes – sheltered housing for tenants with low support needs" },
{
"7" => { "value" => "Yes – for tenants with low support needs" },
"2" => { "value" => "Yes – extra care housing" },
"7" => { "value" => "Yes - other" },
"8" => { "value" => "Yes other" },
"3" => { "value" => "No" },
"divider" => { "value" => true },
"4" => { "value" => "Don’t know" } }
"4" => { "value" => "Don’t know" },
}
else
{ "1" => { "value" => "Yes – specialist retirement housing" },
"2" => { "value" => "Yes – extra care housing" },
@ -26,5 +28,5 @@ class Form::Lettings::Questions::Sheltered < ::Form::Question
end
end
QUESTION_NUMBER_FROM_YEAR = { 2023 => 29 }.freeze
QUESTION_NUMBER_FROM_YEAR = { 2023 => 29, 2024 => 29, 2025 => 25 }.freeze
end

2
app/models/form/lettings/questions/starter_tenancy_type.rb

@ -65,5 +65,5 @@ class Form::Lettings::Questions::StarterTenancyType < ::Form::Question
end
end
QUESTION_NUMBER_FROM_YEAR = { 2023 => 27 }.freeze
QUESTION_NUMBER_FROM_YEAR = { 2023 => 27, 2024 => 27, 2025 => 28 }.freeze
end

2
app/models/form/lettings/questions/startertenancy.rb

@ -10,5 +10,5 @@ class Form::Lettings::Questions::Startertenancy < ::Form::Question
ANSWER_OPTIONS = { "1" => { "value" => "Yes" }, "2" => { "value" => "No" } }.freeze
QUESTION_NUMBER_FROM_YEAR = { 2023 => 26 }.freeze
QUESTION_NUMBER_FROM_YEAR = { 2023 => 26, 2024 => 26, 2025 => 27 }.freeze
end

2
app/models/form/lettings/questions/supcharg_4_weekly.rb

@ -15,5 +15,5 @@ class Form::Lettings::Questions::Supcharg4Weekly < ::Form::Question
@question_number = QUESTION_NUMBER_FROM_YEAR[form.start_date.year] || QUESTION_NUMBER_FROM_YEAR[QUESTION_NUMBER_FROM_YEAR.keys.max]
end
QUESTION_NUMBER_FROM_YEAR = { 2023 => 98, 2024 => 97 }.freeze
QUESTION_NUMBER_FROM_YEAR = { 2023 => 98, 2024 => 97, 2025 => 95 }.freeze
end

2
app/models/form/lettings/questions/supcharg_bi_weekly.rb

@ -15,5 +15,5 @@ class Form::Lettings::Questions::SupchargBiWeekly < ::Form::Question
@question_number = QUESTION_NUMBER_FROM_YEAR[form.start_date.year] || QUESTION_NUMBER_FROM_YEAR[QUESTION_NUMBER_FROM_YEAR.keys.max]
end
QUESTION_NUMBER_FROM_YEAR = { 2023 => 98, 2024 => 97 }.freeze
QUESTION_NUMBER_FROM_YEAR = { 2023 => 98, 2024 => 97, 2025 => 95 }.freeze
end

2
app/models/form/lettings/questions/supcharg_monthly.rb

@ -15,5 +15,5 @@ class Form::Lettings::Questions::SupchargMonthly < ::Form::Question
@question_number = QUESTION_NUMBER_FROM_YEAR[form.start_date.year] || QUESTION_NUMBER_FROM_YEAR[QUESTION_NUMBER_FROM_YEAR.keys.max]
end
QUESTION_NUMBER_FROM_YEAR = { 2023 => 98, 2024 => 97 }.freeze
QUESTION_NUMBER_FROM_YEAR = { 2023 => 98, 2024 => 97, 2025 => 95 }.freeze
end

2
app/models/form/lettings/questions/supcharg_weekly.rb

@ -15,5 +15,5 @@ class Form::Lettings::Questions::SupchargWeekly < ::Form::Question
@question_number = QUESTION_NUMBER_FROM_YEAR[form.start_date.year] || QUESTION_NUMBER_FROM_YEAR[QUESTION_NUMBER_FROM_YEAR.keys.max]
end
QUESTION_NUMBER_FROM_YEAR = { 2023 => 98, 2024 => 97 }.freeze
QUESTION_NUMBER_FROM_YEAR = { 2023 => 98, 2024 => 97, 2025 => 95 }.freeze
end

2
app/models/form/lettings/questions/tenancy_length.rb

@ -12,5 +12,5 @@ class Form::Lettings::Questions::TenancyLength < ::Form::Question
@question_number = QUESTION_NUMBER_FROM_YEAR[form.start_date.year] || QUESTION_NUMBER_FROM_YEAR[QUESTION_NUMBER_FROM_YEAR.keys.max]
end
QUESTION_NUMBER_FROM_YEAR = { 2023 => 28 }.freeze
QUESTION_NUMBER_FROM_YEAR = { 2023 => 28, 2024 => 28, 2025 => 29 }.freeze
end

2
app/models/form/lettings/questions/tenancy_length_affordable_rent.rb

@ -12,5 +12,5 @@ class Form::Lettings::Questions::TenancyLengthAffordableRent < ::Form::Question
@question_number = QUESTION_NUMBER_FROM_YEAR[form.start_date.year] || QUESTION_NUMBER_FROM_YEAR[QUESTION_NUMBER_FROM_YEAR.keys.max]
end
QUESTION_NUMBER_FROM_YEAR = { 2023 => 28 }.freeze
QUESTION_NUMBER_FROM_YEAR = { 2023 => 28, 2024 => 28, 2025 => 29 }.freeze
end

2
app/models/form/lettings/questions/tenancy_length_intermediate_rent.rb

@ -12,5 +12,5 @@ class Form::Lettings::Questions::TenancyLengthIntermediateRent < ::Form::Questio
@question_number = QUESTION_NUMBER_FROM_YEAR[form.start_date.year] || QUESTION_NUMBER_FROM_YEAR[QUESTION_NUMBER_FROM_YEAR.keys.max]
end
QUESTION_NUMBER_FROM_YEAR = { 2023 => 28 }.freeze
QUESTION_NUMBER_FROM_YEAR = { 2023 => 28, 2024 => 28, 2025 => 29 }.freeze
end

2
app/models/form/lettings/questions/tenancy_length_periodic.rb

@ -12,5 +12,5 @@ class Form::Lettings::Questions::TenancyLengthPeriodic < ::Form::Question
@question_number = QUESTION_NUMBER_FROM_YEAR[form.start_date.year] || QUESTION_NUMBER_FROM_YEAR[QUESTION_NUMBER_FROM_YEAR.keys.max]
end
QUESTION_NUMBER_FROM_YEAR = { 2023 => 28 }.freeze
QUESTION_NUMBER_FROM_YEAR = { 2023 => 28, 2024 => 28, 2025 => 29 }.freeze
end

2
app/models/form/lettings/questions/tenancy_other.rb

@ -8,5 +8,5 @@ class Form::Lettings::Questions::TenancyOther < ::Form::Question
@question_number = QUESTION_NUMBER_FROM_YEAR[form.start_date.year] || QUESTION_NUMBER_FROM_YEAR[QUESTION_NUMBER_FROM_YEAR.keys.max]
end
QUESTION_NUMBER_FROM_YEAR = { 2023 => 27 }.freeze
QUESTION_NUMBER_FROM_YEAR = { 2023 => 27, 2024 => 27, 2025 => 28 }.freeze
end

2
app/models/form/lettings/questions/tenancy_type.rb

@ -65,5 +65,5 @@ class Form::Lettings::Questions::TenancyType < ::Form::Question
end
end
QUESTION_NUMBER_FROM_YEAR = { 2023 => 27 }.freeze
QUESTION_NUMBER_FROM_YEAR = { 2023 => 27, 2024 => 27, 2025 => 28 }.freeze
end

2
app/models/form/lettings/questions/town_or_city.rb

@ -10,5 +10,5 @@ class Form::Lettings::Questions::TownOrCity < ::Form::Question
@hide_question_number_on_page = true
end
QUESTION_NUMBER_FROM_YEAR = { 2023 => 12, 2024 => 13 }.freeze
QUESTION_NUMBER_FROM_YEAR = { 2023 => 12, 2024 => 13, 2025 => 17 }.freeze
end

2
app/models/form/lettings/questions/tshortfall.rb

@ -24,5 +24,5 @@ class Form::Lettings::Questions::Tshortfall < ::Form::Question
@question_number = QUESTION_NUMBER_FROM_YEAR[form.start_date.year] || QUESTION_NUMBER_FROM_YEAR[QUESTION_NUMBER_FROM_YEAR.keys.max]
end
QUESTION_NUMBER_FROM_YEAR = { 2023 => 100, 2024 => 99 }.freeze
QUESTION_NUMBER_FROM_YEAR = { 2023 => 100, 2024 => 99, 2025 => 97 }.freeze
end

2
app/models/form/lettings/questions/tshortfall_known.rb

@ -12,5 +12,5 @@ class Form::Lettings::Questions::TshortfallKnown < ::Form::Question
ANSWER_OPTIONS = { "0" => { "value" => "Yes" }, "1" => { "value" => "No" } }.freeze
QUESTION_NUMBER_FROM_YEAR = { 2023 => 100, 2024 => 99 }.freeze
QUESTION_NUMBER_FROM_YEAR = { 2023 => 100, 2024 => 99, 2025 => 97 }.freeze
end

2
app/models/form/lettings/questions/uprn.rb

@ -35,5 +35,5 @@ class Form::Lettings::Questions::Uprn < ::Form::Question
"\n\n#{value.join("\n")}"
end
QUESTION_NUMBER_FROM_YEAR = { 2023 => 11, 2024 => 12 }.freeze
QUESTION_NUMBER_FROM_YEAR = { 2023 => 11, 2024 => 12, 2025 => 16 }.freeze
end

2
app/models/form/lettings/questions/uprn_known.rb

@ -30,5 +30,5 @@ class Form::Lettings::Questions::UprnKnown < ::Form::Question
I18n.t("validations.property.uprn_known.invalid")
end
QUESTION_NUMBER_FROM_YEAR = { 2023 => 11, 2024 => 12 }.freeze
QUESTION_NUMBER_FROM_YEAR = { 2023 => 11, 2024 => 12, 2025 => 16 }.freeze
end

3
app/models/form/page.rb

@ -1,7 +1,7 @@
class Form::Page
attr_accessor :id, :header_partial, :description, :questions, :depends_on, :title_text,
:informative_text, :subsection, :hide_subsection_label, :next_unresolved_page_id,
:skip_text, :interruption_screen_question_ids, :submit_text
:skip_text, :interruption_screen_question_ids, :submit_text, :question_number
def initialize(id, hsh, subsection)
@id = id
@ -11,6 +11,7 @@ class Form::Page
@header_partial = hsh["header_partial"]
@description = hsh["description"]
@questions = hsh["questions"].map { |q_id, q| Form::Question.new(q_id, q, self) }
@question_number = hsh["question_number"]
@depends_on = hsh["depends_on"]
@title_text = hsh["title_text"]
@informative_text = hsh["informative_text"]

3
app/models/form/sales/pages/address_fallback.rb

@ -11,6 +11,7 @@ class Form::Sales::Pages::AddressFallback < ::Form::Page
{ "uprn_known" => 0, "address_options_present?" => false },
{ "uprn_confirmed" => 0, "address_options_present?" => false },
]
@question_number = QUESTION_NUMBER_FROM_YEAR[form.start_date.year] || QUESTION_NUMBER_FROM_YEAR[QUESTION_NUMBER_FROM_YEAR.keys.max]
end
def questions
@ -22,4 +23,6 @@ class Form::Sales::Pages::AddressFallback < ::Form::Page
Form::Sales::Questions::PostcodeForFullAddress.new(nil, nil, self),
]
end
QUESTION_NUMBER_FROM_YEAR = { 2024 => 16, 2025 => 16 }.freeze
end

3
app/views/bulk_upload_lettings_results/show.html.erb

@ -7,7 +7,8 @@
<div class="govuk-grid-row">
<div class="govuk-grid-column-two-thirds">
<span class="govuk-caption-l">Upload lettings logs in bulk (<%= @bulk_upload.year_combo %>)</span>
<h1 class="govuk-heading-l">We found <%= pluralize(@bulk_upload.bulk_upload_errors.count, "error") %> in your file</h1>
<% error_word = @bulk_upload.bulk_upload_errors.not_potential.any? ? "error" : "discrepancy" %>
<h1 class="govuk-heading-l">We found <%= pluralize(@bulk_upload.bulk_upload_errors.count, error_word) %> in your file</h1>
<div class="govuk-body">
Here’s a list of everything that you need to fix your spreadsheet. You can download the <%= govuk_link_to "specification", Forms::BulkUploadForm::PrepareYourFile.new(year: @bulk_upload.year, log_type: "lettings").specification_path, target: "_blank" %> to help you fix the cells in your CSV file.

3
app/views/bulk_upload_sales_results/show.html.erb

@ -7,7 +7,8 @@
<div class="govuk-grid-row">
<div class="govuk-grid-column-two-thirds">
<span class="govuk-caption-l">Upload sales logs in bulk (<%= @bulk_upload.year_combo %>)</span>
<h1 class="govuk-heading-l">We found <%= pluralize(@bulk_upload.bulk_upload_errors.count, "error") %> in your file</h1>
<% error_word = @bulk_upload.bulk_upload_errors.not_potential.any? ? "error" : "discrepancy" %>
<h1 class="govuk-heading-l">We found <%= pluralize(@bulk_upload.bulk_upload_errors.count, error_word) %> in your file</h1>
<div class="govuk-body">
Here’s a list of everything that you need to fix your spreadsheet. You can download the <%= govuk_link_to "specification", Forms::BulkUploadForm::PrepareYourFile.new(year: @bulk_upload.year, log_type: "sales").specification_path, target: "_blank" %> to help you fix the cells in your CSV file.

2
app/views/csv_downloads/show.html.erb

@ -1,4 +1,4 @@
<% title = "Downlaod CSV file" %>
<% title = "Download CSV file" %>
<% content_for :title, title %>
<div class="govuk-grid-row">

2
app/views/form/page.html.erb

@ -27,7 +27,7 @@
<% if @page.header_partial.present? %>
<%= render partial: "form/headers/#{@page.header_partial}", locals: { log: @log } %>
<% else %>
<%= @page.header %>
<%= @page.question_number ? "Q#{@page.question_number} - #{@page.header}" : @page.header %>
<% end %>
</h1>
<% end %>

2
config/locales/forms/2024/lettings/property_information.en.yml

@ -51,7 +51,7 @@ en:
question_text: "Select the correct address"
address:
page_header: "Q12 - What is the property's address?"
page_header: "What is the property's address?"
address_line1:
check_answer_label: "Address lines 1 and 2"
check_answer_prompt: "Enter address lines 1 and 2"

2
config/locales/forms/2024/sales/property_information.en.yml

@ -44,7 +44,7 @@ en:
question_text: "Select the correct address"
address:
page_header: "Q12 - What is the property's address?"
page_header: "What is the property's address?"
address_line1:
check_answer_label: "Address lines 1 and 2"
check_answer_prompt: "Enter address lines 1 and 2"

10
config/locales/forms/2025/lettings/property_information.en.yml

@ -51,7 +51,7 @@ en:
question_text: "Select the correct address"
address:
page_header: "Q12 - What is the property's address?"
page_header: "What is the property's address?"
address_line1:
check_answer_label: "Address lines 1 and 2"
check_answer_prompt: "Enter address lines 1 and 2"
@ -149,7 +149,7 @@ en:
sheltered:
page_header: ""
check_answer_label: "Letting in sheltered accommodation"
check_answer_prompt: "Tell us if letting is in sheltered accommodation"
hint_text: "Sheltered housing and special retirement housing are for tenants with low-level care and support needs. This typically provides some limited support to enable independent living, such as alarm-based assistance or a scheme manager.</br></br>Extra care housing is for tenants with medium to high care and support needs, often with 24 hour access to support staff provided by an agency registered with the Care Quality Commission."
question_text: "Is this letting in sheltered accommodation?"
check_answer_label: "Letting is older people’s housing"
check_answer_prompt: "Tell us if letting is older people’s housing"
hint_text: "This includes retirement living, sheltered housing and extra care housing. There is no national set limit for \"older people\", please answer based on your own policies.</br></br>Extra care housing is for tenants with medium to high care and support needs, often with 24 hour access to support staff provided by an agency registered with the Care Quality Commission."
question_text: "Is this property older people’s housing?"

2
config/locales/forms/2025/sales/property_information.en.yml

@ -44,7 +44,7 @@ en:
question_text: "Select the correct address"
address:
page_header: "Q12 - What is the property's address?"
page_header: "What is the property's address?"
address_line1:
check_answer_label: "Address lines 1 and 2"
check_answer_prompt: "Enter address lines 1 and 2"

4
config/locales/forms/2025/sales/setup.en.yml

@ -42,8 +42,8 @@ en:
page_header: ""
check_answer_label: "Purchase made under ownership scheme"
check_answer_prompt: "Tell us if purchase made under ownership scheme"
hint_text: ""
question_text: "Was this purchase made through an ownership scheme?"
hint_text: "Sales logs are not required for outright and other sales."
question_text: "Select the type of sale"
staircasing:
page_header: ""

2
config/locales/validations/lettings/2024/bulk_upload.en.yml

@ -38,7 +38,7 @@ en:
condition_effects:
no_choices: "You cannot answer this question as you told us nobody in the household has a physical or mental health condition (or other illness) expected to last 12 months or more."
reason:
renewal_reason_needed: "The reason for leaving must be \"End of social or private sector tenancy - no fault\", \"End of social or private sector tenancy - evicted due to anti-social behaviour (ASB)\", \"End of social or private sector tenancy - evicted due to rent arrears\" or \"End of social or private sector tenancy - evicted for any other reason\"."
renewal_reason_needed: "You said this letting is a renewal to the same tenant in the same property in the set up section. This means the tenant's main reason for the household leaving their last settled home must be \"End of social or private sector tenancy - no fault\", \"End of social or private sector tenancy - evicted due to anti-social behaviour (ASB)\", \"End of social or private sector tenancy - evicted due to rent arrears\" or \"End of social or private sector tenancy - evicted for any other reason\"."
referral:
general_needs_prp_referred_by_la: "The source of the referral cannot be referred by local authority housing department for a general needs log."
nominated_by_local_ha_but_la: "The source of the referral cannot be Nominated by local housing authority as your organisation is a local authority."

4
db/migrate/20211126142105_user_case_logs_belong_to_organisation.rb

@ -5,8 +5,8 @@ class UserCaseLogsBelongToOrganisation < ActiveRecord::Migration[6.1]
t.belongs_to :organisation
end
change_table :case_logs, bulk: true do |t|
t.belongs_to :owning_organisation, class_name: "Organisation"
t.belongs_to :managing_organisation, class_name: "Organisation"
t.belongs_to :owning_organisation
t.belongs_to :managing_organisation
end
end

2
db/migrate/20220323094418_create_data_protection_confirmation.rb

@ -2,7 +2,7 @@ class CreateDataProtectionConfirmation < ActiveRecord::Migration[7.0]
def change
create_table :data_protection_confirmations do |t|
t.belongs_to :organisation
t.belongs_to :data_protection_officer, class_name: "User", index: { name: :dpo_user_id }
t.belongs_to :data_protection_officer, index: { name: :dpo_user_id }
t.column :confirmed, :boolean
t.column :old_id, :string
t.column :old_org_id, :string

2
db/migrate/20220427160536_add_created_by_to_case_logs.rb

@ -1,7 +1,7 @@
class AddCreatedByToCaseLogs < ActiveRecord::Migration[7.0]
def change
change_table :case_logs, bulk: true do |t|
t.belongs_to :created_by, class_name: "User"
t.belongs_to :created_by
end
end
end

6
db/migrate/20220826093411_add_sales_log.rb

@ -4,9 +4,9 @@ class AddSalesLog < ActiveRecord::Migration[7.0]
t.integer :status, default: 0
t.datetime :saledate
t.timestamps
t.references :owning_organisation, class_name: "Organisation", foreign_key: { to_table: :organisations, on_delete: :cascade }
t.references :managing_organisation, class_name: "Organisation"
t.references :created_by, class_name: "User"
t.references :owning_organisation, foreign_key: { to_table: :organisations, on_delete: :cascade }
t.references :managing_organisation
t.references :created_by
end
end
end

4
db/migrate/20221207141947_add_updated_by_to_logs.rb

@ -1,10 +1,10 @@
class AddUpdatedByToLogs < ActiveRecord::Migration[7.0]
def change
change_table :lettings_logs, bulk: true do |t|
t.belongs_to :updated_by, class_name: "User"
t.belongs_to :updated_by
end
change_table :sales_logs, bulk: true do |t|
t.belongs_to :updated_by, class_name: "User"
t.belongs_to :updated_by
end
end
end

2
db/migrate/20230530094653_add_data_sharing_agreement.rb

@ -2,7 +2,7 @@ class AddDataSharingAgreement < ActiveRecord::Migration[7.0]
def change
create_table :data_sharing_agreements do |t|
t.belongs_to :organisation
t.belongs_to :data_protection_officer, class_name: "User"
t.belongs_to :data_protection_officer
t.datetime :signed_at, null: false
t.string :organisation_name, null: false

2
db/migrate/20231121131725_add_sales_managing_organisation.rb

@ -1,7 +1,7 @@
class AddSalesManagingOrganisation < ActiveRecord::Migration[7.0]
def change
change_table :sales_logs, bulk: true do |t|
t.references :managing_organisation, class_name: "Organisation"
t.references :managing_organisation
end
end
end

4
db/migrate/20240408102550_add_created_by.rb

@ -1,11 +1,11 @@
class AddCreatedBy < ActiveRecord::Migration[7.0]
def change
change_table :sales_logs do |t|
t.references :created_by, class_name: "User"
t.references :created_by
end
change_table :lettings_logs do |t|
t.references :created_by, class_name: "User"
t.references :created_by
end
end
end

10
db/schema.rb

@ -245,14 +245,14 @@ ActiveRecord::Schema[7.2].define(version: 2025_01_10_150609) do
t.integer "hb"
t.integer "hbrentshortfall"
t.integer "property_relet"
t.datetime "mrcdate"
t.datetime "mrcdate", precision: nil
t.integer "incref"
t.datetime "startdate"
t.datetime "startdate", precision: nil
t.integer "armedforces"
t.integer "first_time_property_let_as_social_housing"
t.integer "unitletas"
t.integer "builtype"
t.datetime "voiddate"
t.datetime "voiddate", precision: nil
t.bigint "owning_organisation_id"
t.bigint "managing_organisation_id"
t.integer "renttype"
@ -822,8 +822,8 @@ ActiveRecord::Schema[7.2].define(version: 2025_01_10_150609) do
t.string "name"
t.bigint "organisation_id"
t.integer "sign_in_count", default: 0, null: false
t.datetime "current_sign_in_at"
t.datetime "last_sign_in_at"
t.datetime "current_sign_in_at", precision: nil
t.datetime "last_sign_in_at", precision: nil
t.string "current_sign_in_ip"
t.string "last_sign_in_ip"
t.integer "role"

10
docs/Gemfile.lock

@ -210,11 +210,11 @@ GEM
jekyll-feed (~> 0.9)
jekyll-seo-tag (~> 2.1)
minitest (5.19.0)
nokogiri (1.16.5-arm64-darwin)
nokogiri (1.18.3-arm64-darwin)
racc (~> 1.4)
nokogiri (1.16.5-x86_64-darwin)
nokogiri (1.18.3-x86_64-darwin)
racc (~> 1.4)
nokogiri (1.16.5-x86_64-linux)
nokogiri (1.18.3-x86_64-linux-gnu)
racc (~> 1.4)
octokit (4.25.1)
faraday (>= 1, < 3)
@ -222,7 +222,7 @@ GEM
pathutil (0.16.2)
forwardable-extended (~> 2.6)
public_suffix (4.0.7)
racc (1.7.3)
racc (1.8.1)
rb-fsevent (0.11.2)
rb-inotify (0.10.1)
ffi (~> 1.0)
@ -264,4 +264,4 @@ DEPENDENCIES
webrick
BUNDLED WITH
2.3.14
2.6.4

4
docs/setup.md

@ -66,8 +66,8 @@ We recommend using [nvm](https://github.com/nvm-sh/nvm) to manage NodeJS version
4. Install Ruby and Bundler
```bash
rbenv install 3.1.4
rbenv global 3.1.4
rbenv install 3.1.6
rbenv global 3.1.6
source ~/.bashrc
gem install bundler
```

20
lib/tasks/correct_checkbox_values.rake

@ -0,0 +1,20 @@
desc "Update BU reasonable preference and illness type checkbox values"
task correct_checkbox_values: :environment do
any_reasonpref_selected = "rp_homeless = 1 OR rp_hardship = 1 OR rp_medwel = 1 OR rp_insan_unsat = 1 OR rp_dontknow = 1"
any_reasonpref_is_null = "rp_homeless IS NULL OR rp_hardship IS NULL OR rp_medwel IS NULL OR rp_insan_unsat IS NULL OR rp_dontknow IS NULL"
LettingsLog.filter_by_year(2024).where(reasonpref: 1).where(any_reasonpref_selected).where(any_reasonpref_is_null).find_each do |lettings_log|
unless lettings_log.save
Rails.logger.info("Failed to save reasonpref for LettingsLog with id #{lettings_log.id}: #{lettings_log.errors.full_messages}")
end
end
any_illness_selected = "illness_type_1 = 1 OR illness_type_2 = 1 OR illness_type_3 = 1 OR illness_type_4 = 1 OR illness_type_5 = 1 OR illness_type_6 = 1 OR illness_type_7 = 1 OR illness_type_8 = 1 OR illness_type_9 = 1 OR illness_type_10 = 1"
any_illness_is_null = "illness_type_1 IS NULL OR illness_type_2 IS NULL OR illness_type_3 IS NULL OR illness_type_4 IS NULL OR illness_type_5 IS NULL OR illness_type_6 IS NULL OR illness_type_7 IS NULL OR illness_type_8 IS NULL OR illness_type_9 IS NULL OR illness_type_10 IS NULL"
LettingsLog.filter_by_year(2024).where(illness: 1).where(any_illness_selected).where(any_illness_is_null).find_each do |lettings_log|
unless lettings_log.save
Rails.logger.info("Failed to save illness for LettingsLog with id #{lettings_log.id}: #{lettings_log.errors.full_messages}")
end
end
end

2
spec/components/bulk_upload_error_row_component_spec.rb

@ -148,7 +148,7 @@ RSpec.describe BulkUploadErrorRowComponent, type: :component do
it "renders the potential errors section" do
result = render_inline(described_class.new(bulk_upload_errors:))
expect(result).to have_content("Potential errors")
expect(result).to have_content("Confirmation needed")
end
it "renders the potential error message" do

4
spec/components/bulk_upload_summary_component_spec.rb

@ -64,8 +64,8 @@ RSpec.describe BulkUploadSummaryComponent, type: :component do
it "shows the potential errors status and error count" do
result = render_inline(described_class.new(bulk_upload:))
expect(result).to have_content("Potential errors in CSV")
expect(result).to have_content("2 potential errors")
expect(result).to have_content("Confirmation needed in CSV")
expect(result).to have_content("2 confirmations needed")
expect(result).to have_content("16 total logs")
expect(result).to have_no_content("errors on important")
expect(result).to have_no_content("critical")

24
spec/features/sales_log_spec.rb

@ -228,6 +228,30 @@ RSpec.describe "Sales Log Features" do
expect(page).to have_current_path("/sales-logs/csv-download?codes_only=false&search=1")
end
end
context "when displaying the question number in the page header" do
let(:sales_log) { FactoryBot.create(:sales_log, :shared_ownership_setup_complete, jointpur: 2, owning_organisation: user.organisation, assigned_to: user) }
context "when visiting the address page" do
before do
visit("/sales-logs/#{sales_log.id}/address")
end
it "displays the question number in the page header" do
expect(page).to have_content("Q16")
end
end
context "when visiting the about staircasing page" do
before do
visit("/sales-logs/#{sales_log.id}/about-staircasing-not-joint-purchase")
end
it "displays the question number in the page header" do
expect(page).to have_content(/Shared ownership scheme\s*About the staircasing transaction/)
end
end
end
end
end

2
spec/fixtures/files/lettings_log_csv_export_codes_23.csv vendored

File diff suppressed because one or more lines are too long

2
spec/fixtures/files/lettings_log_csv_export_codes_24.csv vendored

File diff suppressed because one or more lines are too long

2
spec/fixtures/files/lettings_log_csv_export_labels_23.csv vendored

File diff suppressed because one or more lines are too long

2
spec/fixtures/files/lettings_log_csv_export_labels_24.csv vendored

File diff suppressed because one or more lines are too long

2
spec/fixtures/files/lettings_log_csv_export_non_support_codes_23.csv vendored

File diff suppressed because one or more lines are too long

2
spec/fixtures/files/lettings_log_csv_export_non_support_codes_24.csv vendored

File diff suppressed because one or more lines are too long

2
spec/fixtures/files/lettings_log_csv_export_non_support_labels_23.csv vendored

File diff suppressed because one or more lines are too long

2
spec/fixtures/files/lettings_log_csv_export_non_support_labels_24.csv vendored

File diff suppressed because one or more lines are too long

216
spec/lib/tasks/correct_checkbox_values_spec.rb

@ -0,0 +1,216 @@
require "rails_helper"
require "rake"
RSpec.describe "correct_checkbox_values" do
describe ":correct_checkbox_values", type: :task do
subject(:task) { Rake::Task["correct_checkbox_values"] }
let(:organisation) { create(:organisation, rent_periods: [2]) }
let(:user) { create(:user, organisation:) }
before do
Rake.application.rake_require("tasks/correct_checkbox_values")
Rake::Task.define_task(:environment)
task.reenable
end
context "when the rake task is run" do
context "and any of the reasonable_preference_reason options are 1" do
let(:bulk_upload) { create(:bulk_upload, :lettings, year: 2024, rent_type_fix_status: BulkUpload.rent_type_fix_statuses[:not_applied]) }
it "sets the remaining options to 0" do
log = build(:lettings_log, :completed, reasonpref: 1, rp_homeless: 1, rp_hardship: nil, rp_medwel: nil, rp_insan_unsat: nil, rp_dontknow: nil,
bulk_upload:, assigned_to: user)
log.save!(validate: false)
initial_updated_at = log.updated_at
task.invoke
log.reload
expect(log.updated_at).not_to eq(initial_updated_at)
expect(log.status).to eq("completed")
expect(log.rp_homeless).to be(1)
expect(log.rp_hardship).to be(0)
expect(log.rp_medwel).to be(0)
expect(log.rp_insan_unsat).to be(0)
expect(log.rp_dontknow).to be(0)
end
it "updates the reasonable preference reason values on a pending log" do
log = build(:lettings_log, :completed, status: "pending", reasonpref: 1, rp_homeless: 1, rp_hardship: nil, rp_medwel: 1, rp_insan_unsat: nil, rp_dontknow: nil, bulk_upload:, assigned_to: user)
log.save!(validate: false)
initial_updated_at = log.updated_at
expect(log.status).to eq("pending")
task.invoke
log.reload
expect(log.rp_homeless).to be(1)
expect(log.rp_hardship).to be(0)
expect(log.rp_medwel).to be(1)
expect(log.rp_insan_unsat).to be(0)
expect(log.rp_dontknow).to be(0)
expect(log.status).to eq("pending")
expect(log.updated_at).not_to eq(initial_updated_at)
end
it "does not update logs if all unselected reasonable preference reason are alredy 0" do
log = build(:lettings_log, :completed, reasonpref: 1, rp_homeless: 0, rp_hardship: 1, rp_medwel: 0, rp_insan_unsat: 0, rp_dontknow: 0, bulk_upload:, assigned_to: user)
log.save!(validate: false)
initial_updated_at = log.updated_at
expect(log.status).to eq("completed")
task.invoke
log.reload
expect(log.status).to eq("completed")
expect(log.updated_at).to eq(initial_updated_at)
end
it "updates the reasonable preference reason values if some of the checkbox values are nil" do
log = build(:lettings_log, :completed, status: "pending", reasonpref: 1, rp_homeless: 0, rp_hardship: nil, rp_medwel: 1, rp_insan_unsat: 0, rp_dontknow: 0, bulk_upload:, assigned_to: user)
log.save!(validate: false)
initial_updated_at = log.updated_at
expect(log.status).to eq("pending")
task.invoke
log.reload
expect(log.rp_homeless).to be(0)
expect(log.rp_hardship).to be(0)
expect(log.rp_medwel).to be(1)
expect(log.rp_insan_unsat).to be(0)
expect(log.rp_dontknow).to be(0)
expect(log.status).to eq("pending")
expect(log.updated_at).not_to eq(initial_updated_at)
end
it "does not update the reasonable preference reason values on a 2023 log" do
log = build(:lettings_log, :completed, startdate: Time.zone.local(2023, 6, 6), reasonpref: 1, rp_homeless: 0, rp_hardship: nil, rp_medwel: 1, rp_insan_unsat: 0, rp_dontknow: 0, bulk_upload:, assigned_to: user)
log.save!(validate: false)
initial_updated_at = log.updated_at
task.invoke
log.reload
expect(log.updated_at).to eq(initial_updated_at)
end
it "does not update and logs error if a validation triggers" do
log = build(:lettings_log, :completed, postcode_full: "0", reasonpref: 1, rp_homeless: 0, rp_hardship: nil, rp_medwel: 1, rp_insan_unsat: 0, rp_dontknow: 0, bulk_upload:, assigned_to: user)
log.save!(validate: false)
initial_updated_at = log.updated_at
task.invoke
log.reload
expect(log.updated_at).to eq(initial_updated_at)
end
end
context "and any of the illness_type options are 1" do
let(:bulk_upload) { create(:bulk_upload, :lettings, year: 2024, rent_type_fix_status: BulkUpload.rent_type_fix_statuses[:not_applied]) }
it "sets the remaining options to 0" do
log = build(:lettings_log, :completed, illness: 1, illness_type_1: 1, illness_type_2: nil, illness_type_3: nil, illness_type_4: nil, illness_type_5: nil, illness_type_6: nil, illness_type_7: nil, illness_type_8: nil, illness_type_9: nil, illness_type_10: nil,
bulk_upload:, assigned_to: user)
log.save!(validate: false)
initial_updated_at = log.updated_at
task.invoke
log.reload
expect(log.updated_at).not_to eq(initial_updated_at)
expect(log.status).to eq("completed")
expect(log.illness_type_1).to be(1)
expect(log.illness_type_2).to be(0)
expect(log.illness_type_3).to be(0)
expect(log.illness_type_4).to be(0)
expect(log.illness_type_5).to be(0)
expect(log.illness_type_6).to be(0)
expect(log.illness_type_7).to be(0)
expect(log.illness_type_8).to be(0)
expect(log.illness_type_9).to be(0)
expect(log.illness_type_10).to be(0)
end
it "updates the reasonable preference reason values on a pending log" do
log = build(:lettings_log, :completed, status: "pending", illness: 1, illness_type_1: 1, illness_type_2: nil, illness_type_3: nil, illness_type_4: nil, illness_type_5: nil, illness_type_6: nil, illness_type_7: nil, illness_type_8: nil, illness_type_9: nil, illness_type_10: nil, bulk_upload:, assigned_to: user)
log.save!(validate: false)
initial_updated_at = log.updated_at
expect(log.status).to eq("pending")
task.invoke
log.reload
expect(log.illness_type_1).to be(1)
expect(log.illness_type_2).to be(0)
expect(log.illness_type_3).to be(0)
expect(log.illness_type_4).to be(0)
expect(log.illness_type_5).to be(0)
expect(log.illness_type_6).to be(0)
expect(log.illness_type_7).to be(0)
expect(log.illness_type_8).to be(0)
expect(log.illness_type_9).to be(0)
expect(log.illness_type_10).to be(0)
expect(log.status).to eq("pending")
expect(log.updated_at).not_to eq(initial_updated_at)
end
it "does not update logs if all unselected reasonable preference reason are alredy 0" do
log = build(:lettings_log, :completed, illness: 1, illness_type_1: 0, illness_type_2: 1, illness_type_3: 0, illness_type_4: 0, illness_type_5: 0, illness_type_6: 0, illness_type_7: 0, illness_type_8: 0, illness_type_9: 0, illness_type_10: 0, bulk_upload:, assigned_to: user)
log.save!(validate: false)
initial_updated_at = log.updated_at
expect(log.status).to eq("completed")
task.invoke
log.reload
expect(log.status).to eq("completed")
expect(log.updated_at).to eq(initial_updated_at)
end
it "updates the reasonable preference reason values if some of the checkbox values are nil" do
log = build(:lettings_log, :completed, status: "pending", illness: 1, illness_type_1: 0, illness_type_2: nil, illness_type_3: 1, illness_type_4: 0, illness_type_5: 0, illness_type_6: nil, illness_type_7: nil, illness_type_8: nil, illness_type_9: nil, illness_type_10: nil, bulk_upload:, assigned_to: user)
log.save!(validate: false)
initial_updated_at = log.updated_at
expect(log.status).to eq("pending")
task.invoke
log.reload
expect(log.illness_type_1).to be(0)
expect(log.illness_type_2).to be(0)
expect(log.illness_type_3).to be(1)
expect(log.illness_type_4).to be(0)
expect(log.illness_type_5).to be(0)
expect(log.illness_type_6).to be(0)
expect(log.illness_type_7).to be(0)
expect(log.illness_type_8).to be(0)
expect(log.illness_type_9).to be(0)
expect(log.illness_type_10).to be(0)
expect(log.status).to eq("pending")
expect(log.updated_at).not_to eq(initial_updated_at)
end
it "does not update the reasonable preference reason values on a 2023 log" do
log = build(:lettings_log, :completed, startdate: Time.zone.local(2023, 6, 6), illness: 1, illness_type_1: 0, illness_type_2: nil, illness_type_3: 1, illness_type_4: 0, illness_type_5: 0, illness_type_6: nil, illness_type_7: nil, illness_type_8: nil, illness_type_9: nil, illness_type_10: nil, bulk_upload:, assigned_to: user)
log.save!(validate: false)
initial_updated_at = log.updated_at
task.invoke
log.reload
expect(log.updated_at).to eq(initial_updated_at)
end
it "does not update and logs error if a validation triggers" do
log = build(:lettings_log, :completed, postcode_full: "0", illness: 1, illness_type_1: 0, illness_type_2: nil, illness_type_3: 1, illness_type_4: 0, illness_type_5: 0, illness_type_6: nil, illness_type_7: nil, illness_type_8: nil, illness_type_9: nil, illness_type_10: nil, bulk_upload:, assigned_to: user)
log.save!(validate: false)
initial_updated_at = log.updated_at
task.invoke
log.reload
expect(log.updated_at).to eq(initial_updated_at)
end
end
end
end
end

2
spec/mailers/bulk_upload_mailer_spec.rb

@ -113,7 +113,7 @@ RSpec.describe BulkUploadMailer do
title: "Check your file data",
filename: bulk_upload.filename,
upload_timestamp: bulk_upload.created_at.to_fs(:govuk_date_and_time),
description: "Some of your #{bulk_upload.year_combo} lettings data might not be right. Click the link below to review the potential errors, and check your file to see if the data is correct.",
description: "We’ve identified potential discrepancies in your #{bulk_upload.year_combo} lettings data. Please review the flagged information via the link below and cross-reference it with your records to confirm data accuracy.",
cta_link: bulk_upload_lettings_soft_validations_check_url(bulk_upload, page: "confirm-soft-errors"),
},
)

2
spec/models/form/lettings/pages/previous_housing_situation_renewal_spec.rb

@ -3,7 +3,7 @@ require "rails_helper"
RSpec.describe Form::Lettings::Pages::PreviousHousingSituationRenewal, 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)

18
spec/models/form/lettings/questions/first_time_property_let_as_social_housing_spec.rb

@ -33,6 +33,8 @@ RSpec.describe Form::Lettings::Questions::FirstTimePropertyLetAsSocialHousing, t
end
context "with 2024/25 form" do
let(:form) { instance_double(Form, start_date: Time.zone.local(2024, 4, 1)) }
before do
allow(form).to receive(:start_year_2024_or_later?).and_return(true)
end
@ -43,5 +45,21 @@ RSpec.describe Form::Lettings::Questions::FirstTimePropertyLetAsSocialHousing, t
"0" => { "value" => "No", "hint" => "This is a re-let of existing social housing stock." },
})
end
it "has the correct question number" do
expect(question.question_number).to eq(15)
end
end
context "with 2025/26 form" do
let(:form) { instance_double(Form, start_date: Time.zone.local(2025, 4, 1)) }
before do
allow(form).to receive(:start_year_2024_or_later?).and_return(true)
end
it "has the correct question number" do
expect(question.question_number).to eq(12)
end
end
end

24
spec/models/form/lettings/questions/joint_spec.rb

@ -39,4 +39,28 @@ RSpec.describe Form::Lettings::Questions::Joint, type: :model do
it "is not marked as derived" do
expect(question.derived?(nil)).to be false
end
context "with 2024/25 form" do
let(:form) { instance_double(Form, start_date: Time.zone.local(2024, 4, 1)) }
before do
allow(form).to receive(:start_year_2024_or_later?).and_return(true)
end
it "has the correct question number" do
expect(question.question_number).to eq(25)
end
end
context "with 2025/26 form" do
let(:form) { instance_double(Form, start_date: Time.zone.local(2025, 4, 1)) }
before do
allow(form).to receive(:start_year_2024_or_later?).and_return(true)
end
it "has the correct question number" do
expect(question.question_number).to eq(26)
end
end
end

24
spec/models/form/lettings/questions/la_spec.rb

@ -310,4 +310,28 @@ RSpec.describe Form::Lettings::Questions::La, type: :model do
"E06000065" => "North Yorkshire",
})
end
context "with 2024/25 form" do
let(:start_date) { Time.utc(2024, 4, 1) }
before do
allow(subsection.form).to receive(:start_year_2024_or_later?).and_return(true)
end
it "has the correct question number" do
expect(question.question_number).to eq(14)
end
end
context "with 2025/26 form" do
let(:start_date) { Time.utc(2025, 4, 1) }
before do
allow(subsection.form).to receive(:start_year_2024_or_later?).and_return(true)
end
it "has the correct question number" do
expect(question.question_number).to eq(18)
end
end
end

12
spec/models/form/lettings/questions/previous_let_type_spec.rb

@ -44,6 +44,8 @@ RSpec.describe Form::Lettings::Questions::PreviousLetType, type: :model do
end
context "with collection year on or after 2024" do
let(:form) { instance_double(Form, start_date: Time.zone.local(2024, 4, 1)) }
before do
allow(form).to receive(:start_year_2024_or_later?).and_return(true)
end
@ -60,9 +62,15 @@ RSpec.describe Form::Lettings::Questions::PreviousLetType, type: :model do
"3" => { "value" => "Don’t know" },
})
end
it "has the correct question number" do
expect(question.question_number).to eq(17)
end
end
context "with collection year on or after 2025" do
let(:form) { instance_double(Form, start_date: Time.zone.local(2025, 4, 1)) }
before do
allow(form).to receive(:start_year_2025_or_later?).and_return(true)
end
@ -80,5 +88,9 @@ RSpec.describe Form::Lettings::Questions::PreviousLetType, type: :model do
"3" => { "value" => "Don’t know" },
})
end
it "has the correct question number" do
expect(question.question_number).to eq(14)
end
end
end

31
spec/models/form/lettings/questions/previous_tenure_renewal_spec.rb

@ -3,7 +3,8 @@ require "rails_helper"
RSpec.describe Form::Lettings::Questions::PreviousTenureRenewal, 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(:start_year_after_2025) { false }
let(:page) { instance_double(Form::Page, subsection: instance_double(Form::Subsection, form: instance_double(Form, start_date: Time.zone.local(2023, 4, 1), start_year_2025_or_later?: start_year_after_2025))) }
it "has the correct id" do
expect(question.id).to eq("prevten")
@ -21,12 +22,26 @@ RSpec.describe Form::Lettings::Questions::PreviousTenureRenewal, type: :model do
expect(question.derived?(nil)).to be false
end
it "has the correct answer_options" do
expect(question.answer_options).to eq({
"34" => { "value" => "Specialist retirement housing" },
"35" => { "value" => "Extra care housing" },
"36" => { "value" => "Sheltered housing for adults aged under 55 years" },
"6" => { "value" => "Other supported housing" },
})
context "with logs before 2025" do
it "has the correct answer_options" do
expect(question.answer_options).to eq({
"34" => { "value" => "Specialist retirement housing" },
"35" => { "value" => "Extra care housing" },
"36" => { "value" => "Sheltered housing for adults aged under 55 years" },
"6" => { "value" => "Other supported housing" },
})
end
end
context "with logs on or after 2025" do
let(:start_year_after_2025) { true }
it "has the correct answer_options" do
expect(question.answer_options).to eq({
"35" => { "value" => "Extra care housing" },
"38" => { "value" => "Older people’s housing for tenants with low support needs" },
"6" => { "value" => "Other supported housing" },
})
end
end
end

65
spec/models/form/lettings/questions/previous_tenure_spec.rb

@ -22,35 +22,37 @@ RSpec.describe Form::Lettings::Questions::PreviousTenure, type: :model do
expect(question.derived?(nil)).to be false
end
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 or family" },
"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" },
})
context "with start year before 2025" do
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 or family" },
"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
context "with 2025 logs" do
@ -62,14 +64,14 @@ RSpec.describe Form::Lettings::Questions::PreviousTenure, type: :model do
"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" },
"38" => { "value" => "Older people’s housing for tenants with low support needs" },
"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)" },
"39" => { "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" },
@ -82,7 +84,6 @@ RSpec.describe Form::Lettings::Questions::PreviousTenure, type: :model do
"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" },
})

22
spec/models/form/lettings/questions/rsnvac_spec.rb

@ -76,7 +76,13 @@ RSpec.describe Form::Lettings::Questions::Rsnvac, type: :model do
end
end
it "has the correct check_answers_card_number" do
expect(question.check_answers_card_number).to eq(0)
end
context "with 2024/25 form" do
let(:form) { instance_double(Form, start_date: Time.zone.local(2024, 4, 1)) }
before do
allow(form).to receive(:start_year_2024_or_later?).and_return(true)
end
@ -129,9 +135,21 @@ RSpec.describe Form::Lettings::Questions::Rsnvac, type: :model do
},
})
end
it "has the correct question number" do
expect(question.question_number).to eq(18)
end
end
it "has the correct check_answers_card_number" do
expect(question.check_answers_card_number).to eq(0)
context "with 2025/26 form" do
let(:form) { instance_double(Form, start_date: Time.zone.local(2025, 4, 1)) }
before do
allow(form).to receive(:start_year_2024_or_later?).and_return(true)
end
it "has the correct question number" do
expect(question.question_number).to eq(15)
end
end
end

Some files were not shown because too many files have changed in this diff Show More

Loading…
Cancel
Save