Browse Source

Merge branch 'main' into CLDC-3845-bu-new-builds-address

pull/2948/head
kosiakkatrina 2 months ago committed by GitHub
parent
commit
942b291848
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
  1. 54
      Gemfile.lock
  2. 3
      app/models/derived_variables/lettings_log_variables.rb
  3. 11
      app/models/form/lettings/pages/referral_direct.rb
  4. 4
      app/models/form/lettings/pages/referral_general_needs.rb
  5. 12
      app/models/form/lettings/pages/referral_general_needs_prp.rb
  6. 11
      app/models/form/lettings/pages/referral_hsc.rb
  7. 11
      app/models/form/lettings/pages/referral_justice.rb
  8. 11
      app/models/form/lettings/pages/referral_la.rb
  9. 3
      app/models/form/lettings/pages/referral_prp.rb
  10. 10
      app/models/form/lettings/pages/referral_type.rb
  11. 5
      app/models/form/lettings/pages/rent_value_check.rb
  12. 1
      app/models/form/lettings/questions/beds.rb
  13. 1
      app/models/form/lettings/questions/builtype.rb
  14. 1
      app/models/form/lettings/questions/first_time_property_let_as_social_housing.rb
  15. 1
      app/models/form/lettings/questions/major_repairs_date_value_check.rb
  16. 1
      app/models/form/lettings/questions/majorrepairs.rb
  17. 1
      app/models/form/lettings/questions/mrcdate.rb
  18. 1
      app/models/form/lettings/questions/previous_let_type.rb
  19. 26
      app/models/form/lettings/questions/referral_direct.rb
  20. 2
      app/models/form/lettings/questions/referral_general_needs.rb
  21. 105
      app/models/form/lettings/questions/referral_general_needs_prp.rb
  22. 32
      app/models/form/lettings/questions/referral_hsc.rb
  23. 23
      app/models/form/lettings/questions/referral_justice.rb
  24. 29
      app/models/form/lettings/questions/referral_la.rb
  25. 89
      app/models/form/lettings/questions/referral_prp.rb
  26. 38
      app/models/form/lettings/questions/referral_type.rb
  27. 5
      app/models/form/lettings/questions/rent_value_check.rb
  28. 1
      app/models/form/lettings/questions/rsnvac.rb
  29. 1
      app/models/form/lettings/questions/rsnvac_first_let.rb
  30. 1
      app/models/form/lettings/questions/sheltered.rb
  31. 1
      app/models/form/lettings/questions/unittype_gn.rb
  32. 1
      app/models/form/lettings/questions/void_date_value_check.rb
  33. 1
      app/models/form/lettings/questions/voiddate.rb
  34. 1
      app/models/form/lettings/questions/wheelchair.rb
  35. 23
      app/models/form/lettings/subsections/household_situation.rb
  36. 2
      app/models/form/lettings/subsections/income_and_benefits.rb
  37. 19
      app/models/form/lettings/subsections/property_information.rb
  38. 3
      app/models/validations/household_validations.rb
  39. 1
      app/models/validations/property_validations.rb
  40. 31
      app/services/bulk_upload/lettings/year2024/row_parser.rb
  41. 51
      app/services/bulk_upload/lettings/year2025/row_parser.rb
  42. 32
      config/locales/forms/2025/lettings/household_situation.en.yml
  43. 4
      config/locales/validations/lettings/2024/bulk_upload.en.yml
  44. 4
      config/locales/validations/lettings/2025/bulk_upload.en.yml
  45. 5
      db/migrate/20250225180643_add_referral_type_to_lettings_logs.rb
  46. 3
      db/schema.rb
  47. 12
      lib/tasks/recalculate_invalid_reasonpref_dontknow.rake
  48. 1
      spec/factories/lettings_log.rb
  49. 70
      spec/lib/tasks/recalculate_invalid_reasonpref_dontknow_spec.rb
  50. 2
      spec/models/form/lettings/questions/referral_general_needs_prp_spec.rb
  51. 2
      spec/models/form/lettings/questions/referral_general_needs_spec.rb
  52. 4
      spec/models/form/lettings/questions/rsnvac_spec.rb
  53. 4
      spec/models/form/lettings/questions/voiddate_spec.rb
  54. 38
      spec/models/form/lettings/subsections/household_situation_spec.rb
  55. 8
      spec/models/form/lettings/subsections/property_information_spec.rb
  56. 25
      spec/models/validations/household_validations_spec.rb
  57. 1
      spec/models/validations/property_validations_spec.rb
  58. 18
      spec/services/bulk_upload/lettings/year2024/row_parser_spec.rb
  59. 13
      spec/services/bulk_upload/lettings/year2025/row_parser_spec.rb

54
Gemfile.lock

@ -118,7 +118,7 @@ GEM
erubi (~> 1.4) erubi (~> 1.4)
parser (>= 2.4) parser (>= 2.4)
smart_properties smart_properties
bigdecimal (3.1.8) bigdecimal (3.1.9)
bindex (0.8.1) bindex (0.8.1)
bootsnap (1.18.3) bootsnap (1.18.3)
msgpack (~> 1.2) msgpack (~> 1.2)
@ -148,15 +148,15 @@ GEM
coderay (1.1.3) coderay (1.1.3)
coercible (1.0.0) coercible (1.0.0)
descendants_tracker (~> 0.0.1) descendants_tracker (~> 0.0.1)
concurrent-ruby (1.3.4) concurrent-ruby (1.3.5)
connection_pool (2.4.1) connection_pool (2.5.0)
crack (1.0.0) crack (1.0.0)
bigdecimal bigdecimal
rexml rexml
crass (1.0.6) crass (1.0.6)
cssbundling-rails (1.4.0) cssbundling-rails (1.4.0)
railties (>= 6.0.0) railties (>= 6.0.0)
csv (3.3.0) csv (3.3.2)
date (3.4.1) date (3.4.1)
descendants_tracker (0.0.4) descendants_tracker (0.0.4)
thread_safe (~> 0.3, >= 0.3.1) thread_safe (~> 0.3, >= 0.3.1)
@ -188,7 +188,7 @@ GEM
rainbow rainbow
rubocop rubocop
smart_properties smart_properties
erubi (1.13.0) erubi (1.13.1)
et-orbi (1.2.11) et-orbi (1.2.11)
tzinfo tzinfo
event_stream_parser (1.0.0) event_stream_parser (1.0.0)
@ -227,12 +227,13 @@ GEM
hashdiff (1.1.0) hashdiff (1.1.0)
html-attributes-utils (1.0.2) html-attributes-utils (1.0.2)
activesupport (>= 6.1.4.4) activesupport (>= 6.1.4.4)
i18n (1.14.6) i18n (1.14.7)
concurrent-ruby (~> 1.0) concurrent-ruby (~> 1.0)
ice_nine (0.11.2) ice_nine (0.11.2)
iniparse (1.5.0) iniparse (1.5.0)
io-console (0.8.0) io-console (0.8.0)
irb (1.14.1) irb (1.15.1)
pp (>= 0.6.0)
rdoc (>= 4.0.0) rdoc (>= 4.0.0)
reline (>= 0.4.2) reline (>= 0.4.2)
jmespath (1.6.2) jmespath (1.6.2)
@ -259,8 +260,8 @@ GEM
listen (3.9.0) listen (3.9.0)
rb-fsevent (~> 0.10, >= 0.10.3) rb-fsevent (~> 0.10, >= 0.10.3)
rb-inotify (~> 0.9, >= 0.9.10) rb-inotify (~> 0.9, >= 0.9.10)
logger (1.6.2) logger (1.6.6)
loofah (2.23.1) loofah (2.24.0)
crass (~> 1.0.2) crass (~> 1.0.2)
nokogiri (>= 1.12.0) nokogiri (>= 1.12.0)
mail (2.8.1) mail (2.8.1)
@ -285,7 +286,7 @@ GEM
net-protocol net-protocol
net-protocol (0.2.2) net-protocol (0.2.2)
timeout timeout
net-smtp (0.5.0) net-smtp (0.5.1)
net-protocol net-protocol
nio4r (2.7.4) nio4r (2.7.4)
nokogiri (1.18.3-arm64-darwin) nokogiri (1.18.3-arm64-darwin)
@ -318,6 +319,9 @@ GEM
racc racc
pg (1.5.5) pg (1.5.5)
possessive (1.0.1) possessive (1.0.1)
pp (0.6.2)
prettyprint
prettyprint (0.2.0)
propshaft (0.8.0) propshaft (0.8.0)
actionpack (>= 7.0.0) actionpack (>= 7.0.0)
activesupport (>= 7.0.0) activesupport (>= 7.0.0)
@ -329,7 +333,7 @@ GEM
pry-byebug (3.10.1) pry-byebug (3.10.1)
byebug (~> 11.0) byebug (~> 11.0)
pry (>= 0.13, < 0.15) pry (>= 0.13, < 0.15)
psych (5.2.1) psych (5.2.3)
date date
stringio stringio
public_suffix (5.0.4) public_suffix (5.0.4)
@ -339,14 +343,15 @@ GEM
activesupport (>= 3.0.0) activesupport (>= 3.0.0)
raabro (1.4.0) raabro (1.4.0)
racc (1.8.1) racc (1.8.1)
rack (3.1.10) rack (3.1.11)
rack-attack (6.7.0) rack-attack (6.7.0)
rack (>= 1.0, < 4) rack (>= 1.0, < 4)
rack-mini-profiler (3.3.1) rack-mini-profiler (3.3.1)
rack (>= 1.2.0) rack (>= 1.2.0)
rack-session (2.0.0) rack-session (2.1.0)
base64 (>= 0.1.0)
rack (>= 3.0.0) rack (>= 3.0.0)
rack-test (2.1.0) rack-test (2.2.0)
rack (>= 1.3) rack (>= 1.3)
rackup (2.2.1) rackup (2.2.1)
rack (>= 3) rack (>= 3)
@ -368,7 +373,7 @@ GEM
activesupport (>= 5.0.0) activesupport (>= 5.0.0)
minitest minitest
nokogiri (>= 1.6) nokogiri (>= 1.6)
rails-html-sanitizer (1.6.1) rails-html-sanitizer (1.6.2)
loofah (~> 2.21) loofah (~> 2.21)
nokogiri (>= 1.15.7, != 1.16.7, != 1.16.6, != 1.16.5, != 1.16.4, != 1.16.3, != 1.16.2, != 1.16.1, != 1.16.0.rc1, != 1.16.0) nokogiri (>= 1.15.7, != 1.16.7, != 1.16.6, != 1.16.5, != 1.16.4, != 1.16.3, != 1.16.2, != 1.16.1, != 1.16.0.rc1, != 1.16.0)
rails_admin (3.3.0) rails_admin (3.3.0)
@ -392,14 +397,14 @@ GEM
rb-fsevent (0.11.2) rb-fsevent (0.11.2)
rb-inotify (0.10.1) rb-inotify (0.10.1)
ffi (~> 1.0) ffi (~> 1.0)
rdoc (6.8.1) rdoc (6.12.0)
psych (>= 4.0.0) psych (>= 4.0.0)
redcarpet (3.6.0) redcarpet (3.6.0)
redis (4.8.1) redis (4.8.1)
redis-client (0.22.1) redis-client (0.22.1)
connection_pool connection_pool
regexp_parser (2.9.0) regexp_parser (2.9.0)
reline (0.5.12) reline (0.6.0)
io-console (~> 0.5) io-console (~> 0.5)
request_store (1.7.0) request_store (1.7.0)
rack (>= 1.4) rack (>= 1.4)
@ -463,7 +468,7 @@ GEM
ruby-progressbar (1.13.0) ruby-progressbar (1.13.0)
ruby2_keywords (0.0.5) ruby2_keywords (0.0.5)
rubyzip (2.3.2) rubyzip (2.3.2)
securerandom (0.4.0) securerandom (0.4.1)
selenium-webdriver (4.18.1) selenium-webdriver (4.18.1)
base64 (~> 0.2) base64 (~> 0.2)
rexml (~> 3.2, >= 3.2.5) rexml (~> 3.2, >= 3.2.5)
@ -492,21 +497,21 @@ GEM
smart_properties (1.17.0) smart_properties (1.17.0)
stimulus-rails (1.3.3) stimulus-rails (1.3.3)
railties (>= 6.0.0) railties (>= 6.0.0)
stringio (3.1.2) stringio (3.1.5)
thor (1.3.2) thor (1.3.2)
thread_safe (0.3.6) thread_safe (0.3.6)
timecop (0.9.8) timecop (0.9.8)
timeout (0.4.3) timeout (0.4.3)
turbo-rails (2.0.11) turbo-rails (2.0.13)
actionpack (>= 6.0.0) actionpack (>= 7.1.0)
railties (>= 6.0.0) railties (>= 7.1.0)
tzinfo (2.0.6) tzinfo (2.0.6)
concurrent-ruby (~> 1.0) concurrent-ruby (~> 1.0)
uk_postcode (2.1.8) uk_postcode (2.1.8)
unicode-display_width (2.5.0) unicode-display_width (2.5.0)
unread (0.14.0) unread (0.14.0)
activerecord (>= 6.1) activerecord (>= 6.1)
uri (0.13.0) uri (1.0.3)
useragent (0.16.11) useragent (0.16.11)
view_component (3.10.0) view_component (3.10.0)
activesupport (>= 5.2.0, < 8.0) activesupport (>= 5.2.0, < 8.0)
@ -528,7 +533,8 @@ GEM
crack (>= 0.3.2) crack (>= 0.3.2)
hashdiff (>= 0.4.0, < 2.0.0) hashdiff (>= 0.4.0, < 2.0.0)
websocket (1.2.10) websocket (1.2.10)
websocket-driver (0.7.6) websocket-driver (0.7.7)
base64
websocket-extensions (>= 0.1.0) websocket-extensions (>= 0.1.0)
websocket-extensions (0.1.5) websocket-extensions (0.1.5)
xpath (3.2.0) xpath (3.2.0)

3
app/models/derived_variables/lettings_log_variables.rb

@ -157,6 +157,9 @@ module DerivedVariables::LettingsLogVariables
self.is_la_inferred = false self.is_la_inferred = false
end end
self.referral = 7 if referral_type == 6
self.referral = 16 if referral_type == 7
reset_address_fields! if is_supported_housing? reset_address_fields! if is_supported_housing?
set_checkbox_values! set_checkbox_values!

11
app/models/form/lettings/pages/referral_direct.rb

@ -0,0 +1,11 @@
class Form::Lettings::Pages::ReferralDirect < ::Form::Page
def initialize(id, hsh, subsection)
super
@id = "referral_direct"
@depends_on = [{ "referral_type" => 1 }]
end
def questions
@questions ||= [Form::Lettings::Questions::ReferralDirect.new(nil, nil, self)]
end
end

4
app/models/form/lettings/pages/referral.rb → app/models/form/lettings/pages/referral_general_needs.rb

@ -1,4 +1,4 @@
class Form::Lettings::Pages::Referral < ::Form::Page class Form::Lettings::Pages::ReferralGeneralNeeds < ::Form::Page
def initialize(id, hsh, subsection) def initialize(id, hsh, subsection)
super super
@id = "referral" @id = "referral"
@ -7,6 +7,6 @@ class Form::Lettings::Pages::Referral < ::Form::Page
end end
def questions def questions
@questions ||= [Form::Lettings::Questions::Referral.new(nil, nil, self)] @questions ||= [Form::Lettings::Questions::ReferralGeneralNeeds.new(nil, nil, self)]
end end
end end

12
app/models/form/lettings/pages/referral_general_needs_prp.rb

@ -0,0 +1,12 @@
class Form::Lettings::Pages::ReferralGeneralNeedsPrp < ::Form::Page
def initialize(id, hsh, subsection)
super
@id = "referral_prp"
@copy_key = "lettings.household_situation.referral.general_needs.prp"
@depends_on = [{ "owning_organisation_provider_type" => "PRP", "needstype" => 1, "renewal" => 0 }]
end
def questions
@questions ||= [Form::Lettings::Questions::ReferralGeneralNeedsPrp.new(nil, nil, self)]
end
end

11
app/models/form/lettings/pages/referral_hsc.rb

@ -0,0 +1,11 @@
class Form::Lettings::Pages::ReferralHsc < ::Form::Page
def initialize(id, hsh, subsection)
super
@id = "referral_hsc"
@depends_on = [{ "referral_type" => 4 }]
end
def questions
@questions ||= [Form::Lettings::Questions::ReferralHsc.new(nil, nil, self)]
end
end

11
app/models/form/lettings/pages/referral_justice.rb

@ -0,0 +1,11 @@
class Form::Lettings::Pages::ReferralJustice < ::Form::Page
def initialize(id, hsh, subsection)
super
@id = "referral_justice"
@depends_on = [{ "referral_type" => 5 }]
end
def questions
@questions ||= [Form::Lettings::Questions::ReferralJustice.new(nil, nil, self)]
end
end

11
app/models/form/lettings/pages/referral_la.rb

@ -0,0 +1,11 @@
class Form::Lettings::Pages::ReferralLa < ::Form::Page
def initialize(id, hsh, subsection)
super
@id = "referral_la"
@depends_on = [{ "referral_type" => 2 }]
end
def questions
@questions ||= [Form::Lettings::Questions::ReferralLa.new(nil, nil, self)]
end
end

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

@ -2,8 +2,7 @@ class Form::Lettings::Pages::ReferralPrp < ::Form::Page
def initialize(id, hsh, subsection) def initialize(id, hsh, subsection)
super super
@id = "referral_prp" @id = "referral_prp"
@copy_key = "lettings.household_situation.referral.general_needs.prp" @depends_on = [{ "referral_type" => 3 }]
@depends_on = [{ "owning_organisation_provider_type" => "PRP", "needstype" => 1, "renewal" => 0 }]
end end
def questions def questions

10
app/models/form/lettings/pages/referral_type.rb

@ -0,0 +1,10 @@
class Form::Lettings::Pages::ReferralType < ::Form::Page
def initialize(id, hsh, subsection)
super
@id = "referral_type"
end
def questions
@questions ||= [Form::Lettings::Questions::ReferralType.new(nil, nil, self)]
end
end

5
app/models/form/lettings/pages/rent_value_check.rb

@ -1,5 +1,5 @@
class Form::Lettings::Pages::RentValueCheck < ::Form::Page class Form::Lettings::Pages::RentValueCheck < ::Form::Page
def initialize(id, hsh, subsection, check_answers_card_number: nil) def initialize(id, hsh, subsection)
super(id, hsh, subsection) super(id, hsh, subsection)
@depends_on = [{ "rent_soft_validation_triggered?" => true }] @depends_on = [{ "rent_soft_validation_triggered?" => true }]
@copy_key = "lettings.soft_validations.rent_value_check" @copy_key = "lettings.soft_validations.rent_value_check"
@ -23,11 +23,10 @@ class Form::Lettings::Pages::RentValueCheck < ::Form::Page
}, },
], ],
} }
@check_answers_card_number = check_answers_card_number
end end
def questions def questions
@questions ||= [Form::Lettings::Questions::RentValueCheck.new(nil, nil, self, check_answers_card_number: @check_answers_card_number)] @questions ||= [Form::Lettings::Questions::RentValueCheck.new(nil, nil, self)]
end end
def interruption_screen_question_ids def interruption_screen_question_ids

1
app/models/form/lettings/questions/beds.rb

@ -4,7 +4,6 @@ class Form::Lettings::Questions::Beds < ::Form::Question
@id = "beds" @id = "beds"
@type = "numeric" @type = "numeric"
@width = 2 @width = 2
@check_answers_card_number = 0
@max = 12 @max = 12
@min = 1 @min = 1
@step = 1 @step = 1

1
app/models/form/lettings/questions/builtype.rb

@ -3,7 +3,6 @@ class Form::Lettings::Questions::Builtype < ::Form::Question
super super
@id = "builtype" @id = "builtype"
@type = "radio" @type = "radio"
@check_answers_card_number = 0
@answer_options = ANSWER_OPTIONS @answer_options = ANSWER_OPTIONS
@question_number = QUESTION_NUMBER_FROM_YEAR[form.start_date.year] || QUESTION_NUMBER_FROM_YEAR[QUESTION_NUMBER_FROM_YEAR.keys.max] @question_number = QUESTION_NUMBER_FROM_YEAR[form.start_date.year] || QUESTION_NUMBER_FROM_YEAR[QUESTION_NUMBER_FROM_YEAR.keys.max]
end end

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

@ -3,7 +3,6 @@ class Form::Lettings::Questions::FirstTimePropertyLetAsSocialHousing < ::Form::Q
super super
@id = "first_time_property_let_as_social_housing" @id = "first_time_property_let_as_social_housing"
@type = "radio" @type = "radio"
@check_answers_card_number = 0
@question_number = QUESTION_NUMBER_FROM_YEAR[form.start_date.year] || QUESTION_NUMBER_FROM_YEAR[QUESTION_NUMBER_FROM_YEAR.keys.max] @question_number = QUESTION_NUMBER_FROM_YEAR[form.start_date.year] || QUESTION_NUMBER_FROM_YEAR[QUESTION_NUMBER_FROM_YEAR.keys.max]
end end

1
app/models/form/lettings/questions/major_repairs_date_value_check.rb

@ -4,7 +4,6 @@ class Form::Lettings::Questions::MajorRepairsDateValueCheck < ::Form::Question
@id = "major_repairs_date_value_check" @id = "major_repairs_date_value_check"
@copy_key = "lettings.soft_validations.major_repairs_date_value_check" @copy_key = "lettings.soft_validations.major_repairs_date_value_check"
@type = "interruption_screen" @type = "interruption_screen"
@check_answers_card_number = 0
@answer_options = ANSWER_OPTIONS @answer_options = ANSWER_OPTIONS
@hidden_in_check_answers = { @hidden_in_check_answers = {
"depends_on" => [ "depends_on" => [

1
app/models/form/lettings/questions/majorrepairs.rb

@ -4,7 +4,6 @@ class Form::Lettings::Questions::Majorrepairs < ::Form::Question
@id = "majorrepairs" @id = "majorrepairs"
@copy_key = "lettings.property_information.property_major_repairs.majorrepairs" @copy_key = "lettings.property_information.property_major_repairs.majorrepairs"
@type = "radio" @type = "radio"
@check_answers_card_number = 0
@answer_options = ANSWER_OPTIONS @answer_options = ANSWER_OPTIONS
@conditional_for = { "mrcdate" => [1] } @conditional_for = { "mrcdate" => [1] }
@question_number = QUESTION_NUMBER_FROM_YEAR[form.start_date.year] || QUESTION_NUMBER_FROM_YEAR[QUESTION_NUMBER_FROM_YEAR.keys.max] @question_number = QUESTION_NUMBER_FROM_YEAR[form.start_date.year] || QUESTION_NUMBER_FROM_YEAR[QUESTION_NUMBER_FROM_YEAR.keys.max]

1
app/models/form/lettings/questions/mrcdate.rb

@ -4,7 +4,6 @@ class Form::Lettings::Questions::Mrcdate < ::Form::Question
@id = "mrcdate" @id = "mrcdate"
@copy_key = "lettings.property_information.property_major_repairs.mrcdate" @copy_key = "lettings.property_information.property_major_repairs.mrcdate"
@type = "date" @type = "date"
@check_answers_card_number = 0
@question_number = QUESTION_NUMBER_FROM_YEAR[form.start_date.year] || QUESTION_NUMBER_FROM_YEAR[QUESTION_NUMBER_FROM_YEAR.keys.max] @question_number = QUESTION_NUMBER_FROM_YEAR[form.start_date.year] || QUESTION_NUMBER_FROM_YEAR[QUESTION_NUMBER_FROM_YEAR.keys.max]
end end

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

@ -3,7 +3,6 @@ class Form::Lettings::Questions::PreviousLetType < ::Form::Question
super super
@id = "unitletas" @id = "unitletas"
@type = "radio" @type = "radio"
@check_answers_card_number = 0
@answer_options = answer_options @answer_options = answer_options
@question_number = QUESTION_NUMBER_FROM_YEAR[form.start_date.year] || QUESTION_NUMBER_FROM_YEAR[QUESTION_NUMBER_FROM_YEAR.keys.max] @question_number = QUESTION_NUMBER_FROM_YEAR[form.start_date.year] || QUESTION_NUMBER_FROM_YEAR[QUESTION_NUMBER_FROM_YEAR.keys.max]
end end

26
app/models/form/lettings/questions/referral_direct.rb

@ -0,0 +1,26 @@
class Form::Lettings::Questions::ReferralDirect < ::Form::Question
def initialize(id, hsh, page)
super
@id = "referral"
@copy_key = "lettings.household_situation.referral.direct"
@type = "radio"
@check_answers_card_number = 0
@question_number = QUESTION_NUMBER_FROM_YEAR[form.start_date.year] || QUESTION_NUMBER_FROM_YEAR[QUESTION_NUMBER_FROM_YEAR.keys.max]
end
def answer_options
{
"20" => {
"value" => "Homeless households owed a duty and not on a housing register or waiting list",
},
"2" => {
"value" => "Tenant applied directly for an available property",
},
"8" => {
"value" => "Relocated through official housing mobility scheme",
},
}.freeze
end
QUESTION_NUMBER_FROM_YEAR = { 2025 => 84 }.freeze
end

2
app/models/form/lettings/questions/referral.rb → app/models/form/lettings/questions/referral_general_needs.rb

@ -1,4 +1,4 @@
class Form::Lettings::Questions::Referral < ::Form::Question class Form::Lettings::Questions::ReferralGeneralNeeds < ::Form::Question
def initialize(id, hsh, page) def initialize(id, hsh, page)
super super
@id = "referral" @id = "referral"

105
app/models/form/lettings/questions/referral_general_needs_prp.rb

@ -0,0 +1,105 @@
class Form::Lettings::Questions::ReferralGeneralNeedsPrp < ::Form::Question
def initialize(id, hsh, page)
super
@id = "referral"
@copy_key = "lettings.household_situation.referral.general_needs.prp"
@type = "radio"
@check_answers_card_number = 0
@question_number = QUESTION_NUMBER_FROM_YEAR[form.start_date.year] || QUESTION_NUMBER_FROM_YEAR[QUESTION_NUMBER_FROM_YEAR.keys.max]
end
def answer_options
if form.start_year_2024_or_later?
{
"1" => {
"value" => "Internal transfer",
"hint" => "Where the tenant has moved to another social property owned by the same landlord.",
},
"2" => {
"value" => "Tenant applied directly (no referral or nomination)",
},
"3" => {
"value" => "Nominated by a local housing authority",
},
"8" => {
"value" => "Re-located through official housing mobility scheme",
},
"10" => {
"value" => "Other social landlord",
},
"9" => {
"value" => "Community learning disability team",
},
"14" => {
"value" => "Community mental health team",
},
"15" => {
"value" => "Health service",
},
"18" => {
"value" => "Police, probation, prison or youth offending team – tenant had custodial sentence",
},
"19" => {
"value" => "Police, probation, prison or youth offending team – no custodial sentence",
},
"7" => {
"value" => "Voluntary agency",
},
"17" => {
"value" => "Children’s Social Care",
},
"16" => {
"value" => "Other",
},
}.freeze
else
{
"1" => {
"value" => "Internal transfer",
"hint" => "Where the tenant has moved to another social property owned by the same landlord.",
},
"2" => {
"value" => "Tenant applied directly (no referral or nomination)",
},
"3" => {
"value" => "Nominated by a local housing authority",
},
"4" => {
"value" => "Referred by local authority housing department",
},
"8" => {
"value" => "Re-located through official housing mobility scheme",
},
"10" => {
"value" => "Other social landlord",
},
"9" => {
"value" => "Community learning disability team",
},
"14" => {
"value" => "Community mental health team",
},
"15" => {
"value" => "Health service",
},
"12" => {
"value" => "Police, probation or prison",
},
"7" => {
"value" => "Voluntary agency",
},
"13" => {
"value" => "Youth offending team",
},
"17" => {
"value" => "Children’s Social Care",
},
"16" => {
"value" => "Other",
},
}.freeze
end
end
QUESTION_NUMBER_FROM_YEAR = { 2023 => 85, 2024 => 84 }.freeze
end

32
app/models/form/lettings/questions/referral_hsc.rb

@ -0,0 +1,32 @@
class Form::Lettings::Questions::ReferralHsc < ::Form::Question
def initialize(id, hsh, page)
super
@id = "referral"
@copy_key = "lettings.household_situation.referral.hsc"
@type = "radio"
@check_answers_card_number = 0
@question_number = QUESTION_NUMBER_FROM_YEAR[form.start_date.year] || QUESTION_NUMBER_FROM_YEAR[QUESTION_NUMBER_FROM_YEAR.keys.max]
end
def answer_options
{
"15" => {
"value" => "Health service",
},
"9" => {
"value" => "Community learning disability team",
},
"14" => {
"value" => "Community mental health team",
},
"24" => {
"value" => "Adult social services",
},
"17" => {
"value" => "Children's social care",
},
}.freeze
end
QUESTION_NUMBER_FROM_YEAR = { 2025 => 84 }.freeze
end

23
app/models/form/lettings/questions/referral_justice.rb

@ -0,0 +1,23 @@
class Form::Lettings::Questions::ReferralJustice < ::Form::Question
def initialize(id, hsh, page)
super
@id = "referral"
@copy_key = "lettings.household_situation.referral.justice"
@type = "radio"
@check_answers_card_number = 0
@question_number = QUESTION_NUMBER_FROM_YEAR[form.start_date.year] || QUESTION_NUMBER_FROM_YEAR[QUESTION_NUMBER_FROM_YEAR.keys.max]
end
def answer_options
{
"18" => {
"value" => "With a custodial sentence",
},
"19" => {
"value" => "No custodial sentence",
},
}.freeze
end
QUESTION_NUMBER_FROM_YEAR = { 2025 => 84 }.freeze
end

29
app/models/form/lettings/questions/referral_la.rb

@ -0,0 +1,29 @@
class Form::Lettings::Questions::ReferralLa < ::Form::Question
def initialize(id, hsh, page)
super
@id = "referral"
@copy_key = "lettings.household_situation.referral.la"
@type = "radio"
@check_answers_card_number = 0
@question_number = QUESTION_NUMBER_FROM_YEAR[form.start_date.year] || QUESTION_NUMBER_FROM_YEAR[QUESTION_NUMBER_FROM_YEAR.keys.max]
end
def answer_options
{
"21" => {
"value" => "Local authority lettings",
},
"3" => {
"value" => "PRP lettings nominated by a local authority",
},
"4" => {
"value" => "PRP support lettings referred by a local authority",
},
"22" => {
"value" => "Other",
},
}.freeze
end
QUESTION_NUMBER_FROM_YEAR = { 2025 => 84 }.freeze
end

89
app/models/form/lettings/questions/referral_prp.rb

@ -2,104 +2,25 @@ class Form::Lettings::Questions::ReferralPrp < ::Form::Question
def initialize(id, hsh, page) def initialize(id, hsh, page)
super super
@id = "referral" @id = "referral"
@copy_key = "lettings.household_situation.referral.general_needs.prp" @copy_key = "lettings.household_situation.referral.prp"
@type = "radio" @type = "radio"
@check_answers_card_number = 0 @check_answers_card_number = 0
@question_number = QUESTION_NUMBER_FROM_YEAR[form.start_date.year] || QUESTION_NUMBER_FROM_YEAR[QUESTION_NUMBER_FROM_YEAR.keys.max] @question_number = QUESTION_NUMBER_FROM_YEAR[form.start_date.year] || QUESTION_NUMBER_FROM_YEAR[QUESTION_NUMBER_FROM_YEAR.keys.max]
end end
def answer_options def answer_options
if form.start_year_2024_or_later?
{ {
"1" => { "1" => {
"value" => "Internal transfer", "value" => "Internal transfer from another property with the same landlord",
"hint" => "Where the tenant has moved to another social property owned by the same landlord.",
},
"2" => {
"value" => "Tenant applied directly (no referral or nomination)",
},
"3" => {
"value" => "Nominated by a local housing authority",
},
"8" => {
"value" => "Re-located through official housing mobility scheme",
},
"10" => {
"value" => "Other social landlord",
},
"9" => {
"value" => "Community learning disability team",
},
"14" => {
"value" => "Community mental health team",
},
"15" => {
"value" => "Health service",
},
"18" => {
"value" => "Police, probation, prison or youth offending team – tenant had custodial sentence",
},
"19" => {
"value" => "Police, probation, prison or youth offending team – no custodial sentence",
},
"7" => {
"value" => "Voluntary agency",
},
"17" => {
"value" => "Children’s Social Care",
},
"16" => {
"value" => "Other",
},
}.freeze
else
{
"1" => {
"value" => "Internal transfer",
"hint" => "Where the tenant has moved to another social property owned by the same landlord.",
},
"2" => {
"value" => "Tenant applied directly (no referral or nomination)",
},
"3" => {
"value" => "Nominated by a local housing authority",
},
"4" => {
"value" => "Referred by local authority housing department",
},
"8" => {
"value" => "Re-located through official housing mobility scheme",
}, },
"10" => { "10" => {
"value" => "Other social landlord", "value" => "A different PRP landlord",
},
"9" => {
"value" => "Community learning disability team",
}, },
"14" => { "23" => {
"value" => "Community mental health team",
},
"15" => {
"value" => "Health service",
},
"12" => {
"value" => "Police, probation or prison",
},
"7" => {
"value" => "Voluntary agency",
},
"13" => {
"value" => "Youth offending team",
},
"17" => {
"value" => "Children’s Social Care",
},
"16" => {
"value" => "Other", "value" => "Other",
}, },
}.freeze }.freeze
end end
end
QUESTION_NUMBER_FROM_YEAR = { 2023 => 85, 2024 => 84 }.freeze QUESTION_NUMBER_FROM_YEAR = { 2025 => 84 }.freeze
end end

38
app/models/form/lettings/questions/referral_type.rb

@ -0,0 +1,38 @@
class Form::Lettings::Questions::ReferralType < ::Form::Question
def initialize(id, hsh, page)
super
@id = "referral_type"
@copy_key = "lettings.household_situation.referral.type"
@type = "radio"
@check_answers_card_number = 0
@question_number = QUESTION_NUMBER_FROM_YEAR[form.start_date.year] || QUESTION_NUMBER_FROM_YEAR[QUESTION_NUMBER_FROM_YEAR.keys.max]
end
def answer_options
{
"1" => {
"value" => "Direct",
},
"2" => {
"value" => "From a local authority housing register or waiting list",
},
"3" => {
"value" => "From a PRP-only housing register or waiting list (no local authority involvement)",
},
"4" => {
"value" => "Health and social care services",
},
"5" => {
"value" => "Police, probation, prison or youth offending team",
},
"6" => {
"value" => "Voluntary agency",
},
"7" => {
"value" => "Other",
},
}.freeze
end
QUESTION_NUMBER_FROM_YEAR = { 2025 => 84 }.freeze
end

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

@ -1,10 +1,9 @@
class Form::Lettings::Questions::RentValueCheck < ::Form::Question class Form::Lettings::Questions::RentValueCheck < ::Form::Question
def initialize(id, hsh, page, check_answers_card_number:) def initialize(id, hsh, page)
super(id, hsh, page) super
@id = "rent_value_check" @id = "rent_value_check"
@copy_key = "lettings.soft_validations.rent_value_check" @copy_key = "lettings.soft_validations.rent_value_check"
@type = "interruption_screen" @type = "interruption_screen"
@check_answers_card_number = check_answers_card_number
@answer_options = ANSWER_OPTIONS @answer_options = ANSWER_OPTIONS
@hidden_in_check_answers = { "depends_on" => [{ "rent_value_check" => 0 }, { "rent_value_check" => 1 }] } @hidden_in_check_answers = { "depends_on" => [{ "rent_value_check" => 0 }, { "rent_value_check" => 1 }] }
end end

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

@ -3,7 +3,6 @@ class Form::Lettings::Questions::Rsnvac < ::Form::Question
super super
@id = "rsnvac" @id = "rsnvac"
@type = "radio" @type = "radio"
@check_answers_card_number = 0
@question_number = QUESTION_NUMBER_FROM_YEAR[form.start_date.year] || QUESTION_NUMBER_FROM_YEAR[QUESTION_NUMBER_FROM_YEAR.keys.max] @question_number = QUESTION_NUMBER_FROM_YEAR[form.start_date.year] || QUESTION_NUMBER_FROM_YEAR[QUESTION_NUMBER_FROM_YEAR.keys.max]
end end

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

@ -3,7 +3,6 @@ class Form::Lettings::Questions::RsnvacFirstLet < ::Form::Question
super super
@id = "rsnvac" @id = "rsnvac"
@type = "radio" @type = "radio"
@check_answers_card_number = 0
@answer_options = ANSWER_OPTIONS @answer_options = ANSWER_OPTIONS
@question_number = QUESTION_NUMBER_FROM_YEAR[form.start_date.year] || QUESTION_NUMBER_FROM_YEAR[QUESTION_NUMBER_FROM_YEAR.keys.max] @question_number = QUESTION_NUMBER_FROM_YEAR[form.start_date.year] || QUESTION_NUMBER_FROM_YEAR[QUESTION_NUMBER_FROM_YEAR.keys.max]
end end

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

@ -3,7 +3,6 @@ class Form::Lettings::Questions::Sheltered < ::Form::Question
super super
@id = "sheltered" @id = "sheltered"
@type = "radio" @type = "radio"
@check_answers_card_number = 0
@question_number = QUESTION_NUMBER_FROM_YEAR[form.start_date.year] || QUESTION_NUMBER_FROM_YEAR[QUESTION_NUMBER_FROM_YEAR.keys.max] @question_number = QUESTION_NUMBER_FROM_YEAR[form.start_date.year] || QUESTION_NUMBER_FROM_YEAR[QUESTION_NUMBER_FROM_YEAR.keys.max]
end end

1
app/models/form/lettings/questions/unittype_gn.rb

@ -3,7 +3,6 @@ class Form::Lettings::Questions::UnittypeGn < ::Form::Question
super super
@id = "unittype_gn" @id = "unittype_gn"
@type = "radio" @type = "radio"
@check_answers_card_number = 0
@answer_options = ANSWER_OPTIONS @answer_options = ANSWER_OPTIONS
@question_number = QUESTION_NUMBER_FROM_YEAR[form.start_date.year] || QUESTION_NUMBER_FROM_YEAR[QUESTION_NUMBER_FROM_YEAR.keys.max] @question_number = QUESTION_NUMBER_FROM_YEAR[form.start_date.year] || QUESTION_NUMBER_FROM_YEAR[QUESTION_NUMBER_FROM_YEAR.keys.max]
end end

1
app/models/form/lettings/questions/void_date_value_check.rb

@ -4,7 +4,6 @@ class Form::Lettings::Questions::VoidDateValueCheck < ::Form::Question
@id = "void_date_value_check" @id = "void_date_value_check"
@copy_key = "lettings.soft_validations.void_date_value_check" @copy_key = "lettings.soft_validations.void_date_value_check"
@type = "interruption_screen" @type = "interruption_screen"
@check_answers_card_number = 0
@answer_options = ANSWER_OPTIONS @answer_options = ANSWER_OPTIONS
@hidden_in_check_answers = { "depends_on" => [{ "void_date_value_check" => 0 }, { "void_date_value_check" => 1 }] } @hidden_in_check_answers = { "depends_on" => [{ "void_date_value_check" => 0 }, { "void_date_value_check" => 1 }] }
end end

1
app/models/form/lettings/questions/voiddate.rb

@ -3,7 +3,6 @@ class Form::Lettings::Questions::Voiddate < ::Form::Question
super super
@id = "voiddate" @id = "voiddate"
@type = "date" @type = "date"
@check_answers_card_number = 0
@question_number = QUESTION_NUMBER_FROM_YEAR[form.start_date.year] || QUESTION_NUMBER_FROM_YEAR[QUESTION_NUMBER_FROM_YEAR.keys.max] @question_number = QUESTION_NUMBER_FROM_YEAR[form.start_date.year] || QUESTION_NUMBER_FROM_YEAR[QUESTION_NUMBER_FROM_YEAR.keys.max]
@top_guidance_partial = "void_date" @top_guidance_partial = "void_date"
end end

1
app/models/form/lettings/questions/wheelchair.rb

@ -3,7 +3,6 @@ class Form::Lettings::Questions::Wheelchair < ::Form::Question
super super
@id = "wchair" @id = "wchair"
@type = "radio" @type = "radio"
@check_answers_card_number = 0
@answer_options = ANSWER_OPTIONS @answer_options = ANSWER_OPTIONS
@question_number = QUESTION_NUMBER_FROM_YEAR[form.start_date.year] || QUESTION_NUMBER_FROM_YEAR[QUESTION_NUMBER_FROM_YEAR.keys.max] @question_number = QUESTION_NUMBER_FROM_YEAR[form.start_date.year] || QUESTION_NUMBER_FROM_YEAR[QUESTION_NUMBER_FROM_YEAR.keys.max]
end end

23
app/models/form/lettings/subsections/household_situation.rb

@ -21,11 +21,28 @@ class Form::Lettings::Subsections::HouseholdSituation < ::Form::Subsection
Form::Lettings::Pages::ReasonablePreference.new("reasonable_preference", nil, self), Form::Lettings::Pages::ReasonablePreference.new("reasonable_preference", nil, self),
Form::Lettings::Pages::ReasonablePreferenceReason.new(nil, nil, self), Form::Lettings::Pages::ReasonablePreferenceReason.new(nil, nil, self),
Form::Lettings::Pages::AllocationSystem.new("allocation_system", nil, self), Form::Lettings::Pages::AllocationSystem.new("allocation_system", nil, self),
Form::Lettings::Pages::Referral.new(nil, nil, self), referral_questions,
Form::Lettings::Pages::ReferralValueCheck.new(nil, nil, self),
].flatten.compact
end
def referral_questions
if form.start_year_2025_or_later?
[
Form::Lettings::Pages::ReferralType.new(nil, nil, self),
Form::Lettings::Pages::ReferralDirect.new(nil, nil, self),
Form::Lettings::Pages::ReferralLa.new(nil, nil, self),
Form::Lettings::Pages::ReferralPrp.new(nil, nil, self), Form::Lettings::Pages::ReferralPrp.new(nil, nil, self),
Form::Lettings::Pages::ReferralHsc.new(nil, nil, self),
Form::Lettings::Pages::ReferralJustice.new(nil, nil, self),
]
else
[
Form::Lettings::Pages::ReferralGeneralNeeds.new(nil, nil, self),
Form::Lettings::Pages::ReferralGeneralNeedsPrp.new(nil, nil, self),
Form::Lettings::Pages::ReferralSupportedHousing.new(nil, nil, self), Form::Lettings::Pages::ReferralSupportedHousing.new(nil, nil, self),
Form::Lettings::Pages::ReferralSupportedHousingPrp.new(nil, nil, self), Form::Lettings::Pages::ReferralSupportedHousingPrp.new(nil, nil, self),
Form::Lettings::Pages::ReferralValueCheck.new(nil, nil, self), ]
].compact end
end end
end end

2
app/models/form/lettings/subsections/income_and_benefits.rb

@ -20,7 +20,7 @@ class Form::Lettings::Subsections::IncomeAndBenefits < ::Form::Subsection
Form::Lettings::Pages::RentBiWeekly.new(nil, nil, self), Form::Lettings::Pages::RentBiWeekly.new(nil, nil, self),
Form::Lettings::Pages::Rent4Weekly.new(nil, nil, self), Form::Lettings::Pages::Rent4Weekly.new(nil, nil, self),
Form::Lettings::Pages::RentMonthly.new(nil, nil, self), Form::Lettings::Pages::RentMonthly.new(nil, nil, self),
Form::Lettings::Pages::RentValueCheck.new("brent_rent_value_check", nil, self, check_answers_card_number: 0), Form::Lettings::Pages::RentValueCheck.new("brent_rent_value_check", nil, self),
Form::Lettings::Pages::SchargeValueCheck.new(nil, nil, self), Form::Lettings::Pages::SchargeValueCheck.new(nil, nil, self),
Form::Lettings::Pages::PschargeValueCheck.new(nil, nil, self), Form::Lettings::Pages::PschargeValueCheck.new(nil, nil, self),
Form::Lettings::Pages::SupchargValueCheck.new(nil, nil, self), Form::Lettings::Pages::SupchargValueCheck.new(nil, nil, self),

19
app/models/form/lettings/subsections/property_information.rb

@ -8,19 +8,17 @@ class Form::Lettings::Subsections::PropertyInformation < ::Form::Subsection
def pages def pages
@pages ||= [ @pages ||= [
(first_let_questions if form.start_year_2025_or_later?),
uprn_questions, uprn_questions,
Form::Lettings::Pages::PropertyLocalAuthority.new(nil, nil, self), Form::Lettings::Pages::PropertyLocalAuthority.new(nil, nil, self),
Form::Lettings::Pages::RentValueCheck.new("local_authority_rent_value_check", nil, self, check_answers_card_number: nil), Form::Lettings::Pages::RentValueCheck.new("local_authority_rent_value_check", nil, self),
Form::Lettings::Pages::FirstTimePropertyLetAsSocialHousing.new(nil, nil, self), (first_let_questions unless form.start_year_2025_or_later?),
Form::Lettings::Pages::PropertyLetType.new(nil, nil, self),
Form::Lettings::Pages::PropertyVacancyReasonNotFirstLet.new(nil, nil, self),
Form::Lettings::Pages::PropertyVacancyReasonFirstLet.new(nil, nil, self),
number_of_times_relet, number_of_times_relet,
Form::Lettings::Pages::PropertyUnitType.new(nil, nil, self), Form::Lettings::Pages::PropertyUnitType.new(nil, nil, self),
Form::Lettings::Pages::PropertyBuildingType.new(nil, nil, self), Form::Lettings::Pages::PropertyBuildingType.new(nil, nil, self),
Form::Lettings::Pages::PropertyWheelchairAccessible.new(nil, nil, self), Form::Lettings::Pages::PropertyWheelchairAccessible.new(nil, nil, self),
Form::Lettings::Pages::PropertyNumberOfBedrooms.new(nil, nil, self), Form::Lettings::Pages::PropertyNumberOfBedrooms.new(nil, nil, self),
Form::Lettings::Pages::RentValueCheck.new("beds_rent_value_check", nil, self, check_answers_card_number: 0), Form::Lettings::Pages::RentValueCheck.new("beds_rent_value_check", nil, self),
Form::Lettings::Pages::VoidDate.new(nil, nil, self), Form::Lettings::Pages::VoidDate.new(nil, nil, self),
Form::Lettings::Pages::VoidDateValueCheck.new(nil, nil, self), Form::Lettings::Pages::VoidDateValueCheck.new(nil, nil, self),
Form::Lettings::Pages::PropertyMajorRepairs.new(nil, nil, self), Form::Lettings::Pages::PropertyMajorRepairs.new(nil, nil, self),
@ -48,6 +46,15 @@ class Form::Lettings::Subsections::PropertyInformation < ::Form::Subsection
Form::Lettings::Pages::PropertyNumberOfTimesRelet.new(nil, nil, self) unless form.start_year_2024_or_later? Form::Lettings::Pages::PropertyNumberOfTimesRelet.new(nil, nil, self) unless form.start_year_2024_or_later?
end end
def first_let_questions
[
Form::Lettings::Pages::FirstTimePropertyLetAsSocialHousing.new(nil, nil, self),
Form::Lettings::Pages::PropertyLetType.new(nil, nil, self),
Form::Lettings::Pages::PropertyVacancyReasonNotFirstLet.new(nil, nil, self),
Form::Lettings::Pages::PropertyVacancyReasonFirstLet.new(nil, nil, self),
]
end
def displayed_in_tasklist?(log) def displayed_in_tasklist?(log)
!(log.is_supported_housing? && log.is_renewal?) !(log.is_supported_housing? && log.is_renewal?)
end end

3
app/models/validations/household_validations.rb

@ -32,6 +32,7 @@ module Validations::HouseholdValidations
if record.is_reason_permanently_decanted? && record.referral.present? && !record.is_internal_transfer? if record.is_reason_permanently_decanted? && record.referral.present? && !record.is_internal_transfer?
record.errors.add :referral, I18n.t("validations.lettings.household.referral.leaving_last_settled_home.reason_permanently_decanted") record.errors.add :referral, I18n.t("validations.lettings.household.referral.leaving_last_settled_home.reason_permanently_decanted")
record.errors.add :referral_type, I18n.t("validations.lettings.household.referral.leaving_last_settled_home.reason_permanently_decanted")
record.errors.add :reason, I18n.t("validations.lettings.household.reason.leaving_last_settled_home.not_internal_transfer") record.errors.add :reason, I18n.t("validations.lettings.household.reason.leaving_last_settled_home.not_internal_transfer")
end end
@ -171,6 +172,7 @@ module Validations::HouseholdValidations
label = record.form.get_question("prevten", record).present? ? record.form.get_question("prevten", record).label_from_value(record.prevten) : "" label = record.form.get_question("prevten", record).present? ? record.form.get_question("prevten", record).label_from_value(record.prevten) : ""
record.errors.add :prevten, :internal_transfer_non_social_housing, message: I18n.t("validations.lettings.household.prevten.internal_transfer", prevten: label) record.errors.add :prevten, :internal_transfer_non_social_housing, message: I18n.t("validations.lettings.household.prevten.internal_transfer", prevten: label)
record.errors.add :referral, :internal_transfer_non_social_housing, message: I18n.t("validations.lettings.household.referral.prevten_invalid", prevten: label) record.errors.add :referral, :internal_transfer_non_social_housing, message: I18n.t("validations.lettings.household.referral.prevten_invalid", prevten: label)
record.errors.add :referral_type, :internal_transfer_non_social_housing, message: I18n.t("validations.lettings.household.referral.prevten_invalid", prevten: label)
end end
end end
@ -180,6 +182,7 @@ module Validations::HouseholdValidations
if record.is_internal_transfer? && record.owning_organisation.provider_type == "PRP" && record.is_prevten_la_general_needs? if record.is_internal_transfer? && record.owning_organisation.provider_type == "PRP" && record.is_prevten_la_general_needs?
record.errors.add :prevten, :internal_transfer_fixed_or_lifetime, message: I18n.t("validations.lettings.household.prevten.la_general_needs.internal_transfer") record.errors.add :prevten, :internal_transfer_fixed_or_lifetime, message: I18n.t("validations.lettings.household.prevten.la_general_needs.internal_transfer")
record.errors.add :referral, :internal_transfer_fixed_or_lifetime, message: I18n.t("validations.lettings.household.referral.la_general_needs.internal_transfer") record.errors.add :referral, :internal_transfer_fixed_or_lifetime, message: I18n.t("validations.lettings.household.referral.la_general_needs.internal_transfer")
record.errors.add :referral_type, :internal_transfer_fixed_or_lifetime, message: I18n.t("validations.lettings.household.referral.la_general_needs.internal_transfer")
end end
end end

1
app/models/validations/property_validations.rb

@ -11,6 +11,7 @@ module Validations::PropertyValidations
if record.is_relet_to_temp_tenant? && REFERRAL_INVALID_TMP.include?(record.referral) if record.is_relet_to_temp_tenant? && REFERRAL_INVALID_TMP.include?(record.referral)
record.errors.add :rsnvac, I18n.t("validations.lettings.property.rsnvac.referral_invalid") record.errors.add :rsnvac, I18n.t("validations.lettings.property.rsnvac.referral_invalid")
record.errors.add :referral, :referral_invalid, message: I18n.t("validations.lettings.property.referral.rsnvac_non_temp") record.errors.add :referral, :referral_invalid, message: I18n.t("validations.lettings.property.referral.rsnvac_non_temp")
record.errors.add :referral_type, :referral_invalid, message: I18n.t("validations.lettings.property.referral.rsnvac_non_temp")
end end
if record.renewal.present? && record.renewal.zero? && record.rsnvac == 14 if record.renewal.present? && record.renewal.zero? && record.rsnvac == 14

31
app/services/bulk_upload/lettings/year2024/row_parser.rb

@ -418,6 +418,7 @@ class BulkUpload::Lettings::Year2024::RowParser
validate :validate_no_and_dont_know_disabled_needs_conjunction, on: :after_log validate :validate_no_and_dont_know_disabled_needs_conjunction, on: :after_log
validate :validate_no_housing_needs_questions_answered, on: :after_log validate :validate_no_housing_needs_questions_answered, on: :after_log
validate :validate_reasonable_preference_homeless, on: :after_log validate :validate_reasonable_preference_homeless, on: :after_log
validate :validate_reasonable_preference_dont_know, on: :after_log
validate :validate_condition_effects, on: :after_log validate :validate_condition_effects, on: :after_log
validate :validate_if_log_already_exists, on: :after_log, if: -> { FeatureToggle.bulk_upload_duplicate_log_check_enabled? } validate :validate_if_log_already_exists, on: :after_log, if: -> { FeatureToggle.bulk_upload_duplicate_log_check_enabled? }
@ -735,6 +736,15 @@ private
end end
end end
def validate_reasonable_preference_dont_know
if rp_dontknow_conflict?
errors.add(:field_111, I18n.t("#{ERROR_BASE_KEY}.reasonpref.conflict.dont_know"))
%i[field_107 field_108 field_109 field_110].each do |field|
errors.add(field, I18n.t("#{ERROR_BASE_KEY}.reasonpref.conflict.other")) if send(field) == 1
end
end
end
def validate_reasonable_preference_homeless def validate_reasonable_preference_homeless
reason_fields = %i[field_107 field_108 field_109 field_110 field_111] reason_fields = %i[field_107 field_108 field_109 field_110 field_111]
if field_106 == 1 && reason_fields.all? { |field| attributes[field.to_s].blank? } if field_106 == 1 && reason_fields.all? { |field| attributes[field.to_s].blank? }
@ -1254,11 +1264,11 @@ private
attributes["ppostcode_full"] = ppostcode_full attributes["ppostcode_full"] = ppostcode_full
attributes["reasonpref"] = field_106 attributes["reasonpref"] = field_106
attributes["rp_homeless"] = field_107 attributes["rp_homeless"] = field_107 unless rp_dontknow_conflict?
attributes["rp_insan_unsat"] = field_108 attributes["rp_insan_unsat"] = field_108 unless rp_dontknow_conflict?
attributes["rp_medwel"] = field_109 attributes["rp_medwel"] = field_109 unless rp_dontknow_conflict?
attributes["rp_hardship"] = field_110 attributes["rp_hardship"] = field_110 unless rp_dontknow_conflict?
attributes["rp_dontknow"] = field_111 attributes["rp_dontknow"] = field_111 unless rp_dontknow_conflict?
attributes["cbl"] = cbl attributes["cbl"] = cbl
attributes["chr"] = chr attributes["chr"] = chr
@ -1645,4 +1655,15 @@ private
def bulk_upload_organisation def bulk_upload_organisation
Organisation.find(bulk_upload.organisation_id) Organisation.find(bulk_upload.organisation_id)
end end
def rp_dontknow_conflict?
other_reason_fields = %i[field_107 field_108 field_109 field_110]
if field_106 == 1
selected_reasons = other_reason_fields.select { |field| send(field) == 1 }
dont_know_selected = field_111 == 1
return true if selected_reasons.any? && dont_know_selected
end
false
end
end end

51
app/services/bulk_upload/lettings/year2025/row_parser.rb

@ -417,6 +417,7 @@ class BulkUpload::Lettings::Year2025::RowParser
validate :validate_no_and_dont_know_disabled_needs_conjunction, on: :after_log validate :validate_no_and_dont_know_disabled_needs_conjunction, on: :after_log
validate :validate_no_housing_needs_questions_answered, on: :after_log validate :validate_no_housing_needs_questions_answered, on: :after_log
validate :validate_reasonable_preference_homeless, on: :after_log validate :validate_reasonable_preference_homeless, on: :after_log
validate :validate_reasonable_preference_dont_know, on: :after_log
validate :validate_condition_effects, on: :after_log validate :validate_condition_effects, on: :after_log
validate :validate_if_log_already_exists, on: :after_log, if: -> { FeatureToggle.bulk_upload_duplicate_log_check_enabled? } validate :validate_if_log_already_exists, on: :after_log, if: -> { FeatureToggle.bulk_upload_duplicate_log_check_enabled? }
@ -734,6 +735,15 @@ private
end end
end end
def validate_reasonable_preference_dont_know
if rp_dontknow_conflict?
errors.add(:field_111, I18n.t("#{ERROR_BASE_KEY}.reasonpref.conflict.dont_know"))
%i[field_107 field_108 field_109 field_110].each do |field|
errors.add(field, I18n.t("#{ERROR_BASE_KEY}.reasonpref.conflict.other")) if send(field) == 1
end
end
end
def validate_reasonable_preference_homeless def validate_reasonable_preference_homeless
reason_fields = %i[field_107 field_108 field_109 field_110 field_111] reason_fields = %i[field_107 field_108 field_109 field_110 field_111]
if field_106 == 1 && reason_fields.all? { |field| attributes[field.to_s].blank? } if field_106 == 1 && reason_fields.all? { |field| attributes[field.to_s].blank? }
@ -1078,6 +1088,7 @@ private
accessible_register: %i[field_115], accessible_register: %i[field_115],
letting_allocation: %i[field_112 field_113 field_114 field_115], letting_allocation: %i[field_112 field_113 field_114 field_115],
referral_type: %i[field_116],
referral: %i[field_116], referral: %i[field_116],
net_income_known: %i[field_117], net_income_known: %i[field_117],
@ -1251,11 +1262,11 @@ private
attributes["ppostcode_full"] = ppostcode_full attributes["ppostcode_full"] = ppostcode_full
attributes["reasonpref"] = field_106 attributes["reasonpref"] = field_106
attributes["rp_homeless"] = field_107 attributes["rp_homeless"] = field_107 unless rp_dontknow_conflict?
attributes["rp_insan_unsat"] = field_108 attributes["rp_insan_unsat"] = field_108 unless rp_dontknow_conflict?
attributes["rp_medwel"] = field_109 attributes["rp_medwel"] = field_109 unless rp_dontknow_conflict?
attributes["rp_hardship"] = field_110 attributes["rp_hardship"] = field_110 unless rp_dontknow_conflict?
attributes["rp_dontknow"] = field_111 attributes["rp_dontknow"] = field_111 unless rp_dontknow_conflict?
attributes["cbl"] = cbl attributes["cbl"] = cbl
attributes["chr"] = chr attributes["chr"] = chr
@ -1263,6 +1274,7 @@ private
attributes["accessible_register"] = accessible_register attributes["accessible_register"] = accessible_register
attributes["letting_allocation_unknown"] = letting_allocation_unknown attributes["letting_allocation_unknown"] = letting_allocation_unknown
attributes["referral_type"] = referral_type
attributes["referral"] = field_116 attributes["referral"] = field_116
attributes["net_income_known"] = net_income_known attributes["net_income_known"] = net_income_known
@ -1647,4 +1659,33 @@ private
"R" # refused "R" # refused
end end
end end
def rp_dontknow_conflict?
other_reason_fields = %i[field_107 field_108 field_109 field_110]
if field_106 == 1
selected_reasons = other_reason_fields.select { |field| send(field) == 1 }
dont_know_selected = field_111 == 1
return true if selected_reasons.any? && dont_know_selected
end
false
end
def referral_type
mapping = {
1 => [20, 2, 8],
2 => [21, 3, 4, 22],
3 => [1, 10, 23],
4 => [15, 9, 14, 24, 17],
5 => [18, 19],
6 => [7],
7 => [16],
}
mapping.each do |key, values|
return key if values.include?(field_116)
end
0
end
end end

32
config/locales/forms/2025/lettings/household_situation.en.yml

@ -112,29 +112,39 @@ en:
question_text: "How was this letting allocated?" question_text: "How was this letting allocated?"
referral: referral:
supported_housing: type:
prp:
page_header: "" page_header: ""
check_answer_label: "Source of referral for letting" check_answer_label: "Source of referral for letting"
check_answer_prompt: "" check_answer_prompt: "Select source of referral"
hint_text: ""
question_text: "What was the source of referral for this letting?"
direct:
page_header: ""
check_answer_label: "Source of referral for letting"
check_answer_prompt: "Select source of referral"
hint_text: "" hint_text: ""
question_text: "What was the source of referral for this letting?" question_text: "What was the source of referral for this letting?"
la: la:
page_header: "" page_header: ""
check_answer_label: "Source of referral for letting" check_answer_label: "Source of referral for letting"
check_answer_prompt: "" check_answer_prompt: "Select source of referral"
hint_text: "You told us that you are a local authority. We have removed some options because of this." hint_text: ""
question_text: "What was the source of referral for this letting?" question_text: "What was the source of referral for this letting?"
general_needs:
prp: prp:
page_header: "" page_header: ""
check_answer_label: "Source of referral for letting" check_answer_label: "Source of referral for letting"
check_answer_prompt: "" check_answer_prompt: "Select source of referral"
hint_text: "You told us that the needs type is general needs. We have removed some options because of this." hint_text: ""
question_text: "What was the source of referral for this letting?" question_text: "What was the source of referral for this letting?"
la: hsc:
page_header: "" page_header: ""
check_answer_label: "Source of referral for letting" check_answer_label: "Source of referral for letting"
check_answer_prompt: "" check_answer_prompt: "Select source of referral"
hint_text: "You told us that you are a local authority and that the needs type is general needs. We have removed some options because of this." hint_text: ""
question_text: "What was the source of referral for this letting?"
justice:
page_header: ""
check_answer_label: "Source of referral for letting"
check_answer_prompt: "Select source of referral"
hint_text: ""
question_text: "What was the source of referral for this letting?" question_text: "What was the source of referral for this letting?"

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

@ -58,3 +58,7 @@ en:
invalid: "Select a valid nationality." invalid: "Select a valid nationality."
charges: charges:
missing_charges: "Please enter the %{sentence_fragment}. If there is no %{sentence_fragment}, please enter '0'." missing_charges: "Please enter the %{sentence_fragment}. If there is no %{sentence_fragment}, please enter '0'."
reasonpref:
conflict:
dont_know: "You cannot select 'Don't know' if any of the other reasonable preference reasons are also selected."
other: "You cannot select this reasonable preference reason as you've also selected 'Don't know' as a reason."

4
config/locales/validations/lettings/2025/bulk_upload.en.yml

@ -58,3 +58,7 @@ en:
invalid: "Select a valid nationality." invalid: "Select a valid nationality."
charges: charges:
missing_charges: "Please enter the %{sentence_fragment}. If there is no %{sentence_fragment}, please enter '0'." missing_charges: "Please enter the %{sentence_fragment}. If there is no %{sentence_fragment}, please enter '0'."
reasonpref:
conflict:
dont_know: "You cannot select 'Don't know' if any of the other reasonable preference reasons are also selected."
other: "You cannot select this reasonable preference reason as you've also selected 'Don't know' as a reason."

5
db/migrate/20250225180643_add_referral_type_to_lettings_logs.rb

@ -0,0 +1,5 @@
class AddReferralTypeToLettingsLogs < ActiveRecord::Migration[7.2]
def change
add_column :lettings_logs, :referral_type, :integer
end
end

3
db/schema.rb

@ -10,7 +10,7 @@
# #
# It's strongly recommended that you check this file into your version control system. # It's strongly recommended that you check this file into your version control system.
ActiveRecord::Schema[7.2].define(version: 2025_02_19_122817) do ActiveRecord::Schema[7.2].define(version: 2025_02_25_180643) do
# These are extensions that must be enabled in order to support this database # These are extensions that must be enabled in order to support this database
enable_extension "plpgsql" enable_extension "plpgsql"
@ -373,6 +373,7 @@ ActiveRecord::Schema[7.2].define(version: 2025_02_19_122817) do
t.integer "partner_under_16_value_check" t.integer "partner_under_16_value_check"
t.integer "multiple_partners_value_check" t.integer "multiple_partners_value_check"
t.bigint "created_by_id" t.bigint "created_by_id"
t.integer "referral_type"
t.boolean "manual_address_entry_selected", default: false t.boolean "manual_address_entry_selected", default: false
t.index ["assigned_to_id"], name: "index_lettings_logs_on_assigned_to_id" t.index ["assigned_to_id"], name: "index_lettings_logs_on_assigned_to_id"
t.index ["bulk_upload_id"], name: "index_lettings_logs_on_bulk_upload_id" t.index ["bulk_upload_id"], name: "index_lettings_logs_on_bulk_upload_id"

12
lib/tasks/recalculate_invalid_reasonpref_dontknow.rake

@ -0,0 +1,12 @@
desc "Bulk update logs with invalid rp_dontknow values"
task recalculate_invalid_rpdontknow: :environment do
validation_trigger_condition = "rp_dontknow = 1 AND (rp_homeless = 1 OR rp_insan_unsat = 1 OR rp_medwel = 1 OR rp_hardship = 1)"
LettingsLog.filter_by_year(2024).where(validation_trigger_condition).find_each do |log|
log.rp_dontknow = 0
unless log.save
Rails.logger.info "Could not save changes to lettings log #{log.id}"
end
end
end

1
spec/factories/lettings_log.rb

@ -160,6 +160,7 @@ FactoryBot.define do
is_carehome { 0 } is_carehome { 0 }
declaration { 1 } declaration { 1 }
first_time_property_let_as_social_housing { 0 } first_time_property_let_as_social_housing { 0 }
referral_type { 1 }
referral { 2 } referral { 2 }
uprn_known { 0 } uprn_known { 0 }
joint { 3 } joint { 3 }

70
spec/lib/tasks/recalculate_invalid_reasonpref_dontknow_spec.rb

@ -0,0 +1,70 @@
require "rails_helper"
require "rake"
RSpec.describe "recalculate_invalid_reasonpref_dontknow" do
subject(:task) { Rake::Task["recalculate_invalid_rpdontknow"] }
before do
Rake.application.rake_require("tasks/recalculate_invalid_reasonpref_dontknow")
Rake::Task.define_task(:environment)
task.reenable
end
let(:invalid_logs) { create_list(:lettings_log, 5, :completed, reasonpref: 1, rp_dontknow: 1, rp_homeless: 1, rp_insan_unsat: rand(2), rp_medwel: rand(2), rp_hardship: rand(2), updated_at: Time.zone.local(2024, 4, 2, 12, 0, 0)) }
let(:pre_2024_invalid_logs) do
create_list(:lettings_log, 5, :completed, reasonpref: 1, rp_dontknow: 1, rp_homeless: 1, rp_insan_unsat: rand(2), rp_medwel: rand(2), rp_hardship: rand(2)).each do |log|
log.startdate = Time.zone.local(rand(2021..2023), 4, 1)
log.save!(validate: false)
end
end
let(:valid_logs) { create_list(:lettings_log, 3, :completed, reasonpref: 1, rp_dontknow: 0, rp_homeless: 1, rp_insan_unsat: 1, rp_medwel: rand(2), rp_hardship: rand(2), updated_at: Time.zone.local(2024, 4, 2, 12, 0, 0)) }
it "updates the logs from 2024/25 with invalid rp_dontknow values" do
invalid_logs.each do |log|
expect(log.reasonpref).to eq(1)
expect(log.rp_dontknow).to eq(1)
expect(log.rp_homeless).to eq(1)
end
task.invoke
invalid_logs.each do |log|
log.reload
expect(log.reasonpref).to eq(1)
expect(log.rp_dontknow).to eq(0)
expect(log.rp_homeless).to eq(1)
expect(log.updated_at).not_to eq(Time.zone.local(2024, 4, 2, 12, 0, 0))
end
end
it "does not update the logs pre 2024 with invalid rp_dontknow values" do
pre_2024_invalid_logs.each do |log|
expect(log.reasonpref).to eq(1)
expect(log.rp_dontknow).to eq(1)
expect(log.rp_homeless).to eq(1)
end
task.invoke
pre_2024_invalid_logs.each do |log|
log.reload
expect(log.reasonpref).to eq(1)
expect(log.rp_dontknow).to eq(1)
expect(log.rp_homeless).to eq(1)
end
end
it "does not update the logs with valid rp_dontknow values" do
valid_logs.each do |log|
expect(log.reasonpref).to eq(1)
expect(log.rp_dontknow).to eq(0)
expect(log.rp_homeless).to eq(1)
expect(log.rp_insan_unsat).to eq(1)
end
task.invoke
valid_logs.each do |log|
log.reload
expect(log.reasonpref).to eq(1)
expect(log.rp_dontknow).to eq(0)
expect(log.rp_homeless).to eq(1)
expect(log.rp_insan_unsat).to eq(1)
expect(log.updated_at).to eq(Time.zone.local(2024, 4, 2, 12, 0, 0))
end
end
end

2
spec/models/form/lettings/questions/referral_prp_spec.rb → spec/models/form/lettings/questions/referral_general_needs_prp_spec.rb

@ -1,6 +1,6 @@
require "rails_helper" require "rails_helper"
RSpec.describe Form::Lettings::Questions::ReferralPrp, type: :model do RSpec.describe Form::Lettings::Questions::ReferralGeneralNeedsPrp, type: :model do
subject(:question) { described_class.new(question_id, question_definition, page) } subject(:question) { described_class.new(question_id, question_definition, page) }
let(:question_id) { nil } let(:question_id) { nil }

2
spec/models/form/lettings/questions/referral_spec.rb → spec/models/form/lettings/questions/referral_general_needs_spec.rb

@ -1,6 +1,6 @@
require "rails_helper" require "rails_helper"
RSpec.describe Form::Lettings::Questions::Referral, type: :model do RSpec.describe Form::Lettings::Questions::ReferralGeneralNeeds, type: :model do
subject(:question) { described_class.new(question_id, question_definition, page) } subject(:question) { described_class.new(question_id, question_definition, page) }
let(:question_id) { nil } let(:question_id) { nil }

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

@ -76,10 +76,6 @@ RSpec.describe Form::Lettings::Questions::Rsnvac, type: :model do
end end
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 context "with 2024/25 form" do
let(:form) { instance_double(Form, start_date: Time.zone.local(2024, 4, 1)) } let(:form) { instance_double(Form, start_date: Time.zone.local(2024, 4, 1)) }

4
spec/models/form/lettings/questions/voiddate_spec.rb

@ -15,10 +15,6 @@ RSpec.describe Form::Lettings::Questions::Voiddate, type: :model do
expect(question.id).to eq("voiddate") expect(question.id).to eq("voiddate")
end end
it "has the correct check_answers_card_number" do
expect(question.check_answers_card_number).to eq(0)
end
it "has the correct question_number" do it "has the correct question_number" do
expect(question.question_number).to eq(23) expect(question.question_number).to eq(23)
end end

38
spec/models/form/lettings/subsections/household_situation_spec.rb

@ -19,6 +19,7 @@ RSpec.describe Form::Lettings::Subsections::HouseholdSituation, type: :model do
context "with form year before 2024" do context "with form year before 2024" do
before do before do
allow(form).to receive(:start_year_2024_or_later?).and_return(false) allow(form).to receive(:start_year_2024_or_later?).and_return(false)
allow(form).to receive(:start_year_2025_or_later?).and_return(false)
end end
it "has correct pages" do it "has correct pages" do
@ -46,9 +47,10 @@ RSpec.describe Form::Lettings::Subsections::HouseholdSituation, type: :model do
end end
end end
context "with form year >= 2024" do context "with form year is 2024" do
before do before do
allow(form).to receive(:start_year_2024_or_later?).and_return(true) allow(form).to receive(:start_year_2024_or_later?).and_return(true)
allow(form).to receive(:start_year_2025_or_later?).and_return(false)
end end
it "has correct pages" do it "has correct pages" do
@ -77,6 +79,40 @@ RSpec.describe Form::Lettings::Subsections::HouseholdSituation, type: :model do
end end
end end
context "with form year is 2025" do
before do
allow(form).to receive(:start_year_2024_or_later?).and_return(true)
allow(form).to receive(:start_year_2025_or_later?).and_return(true)
end
it "has correct pages" do
expect(household_situation.pages.map(&:id)).to eq(
%w[
time_lived_in_local_authority
time_on_waiting_list
reason_for_leaving_last_settled_home
reason_for_leaving_last_settled_home_renewal
reasonother_value_check
previous_housing_situation
previous_housing_situation_renewal
homelessness
previous_postcode
previous_local_authority
reasonable_preference
reasonable_preference_reason
allocation_system
referral_type
referral_direct
referral_la
referral_prp
referral_hsc
referral_justice
referral_value_check
],
)
end
end
it "has the correct id" do it "has the correct id" do
expect(household_situation.id).to eq("household_situation") expect(household_situation.id).to eq("household_situation")
end end

8
spec/models/form/lettings/subsections/property_information_spec.rb

@ -97,14 +97,14 @@ RSpec.describe Form::Lettings::Subsections::PropertyInformation, type: :model do
it "has correct pages" do it "has correct pages" do
expect(property_information.pages.map(&:id)).to eq( expect(property_information.pages.map(&:id)).to eq(
%w[ %w[
address_search
address
property_local_authority
local_authority_rent_value_check
first_time_property_let_as_social_housing first_time_property_let_as_social_housing
property_let_type property_let_type
property_vacancy_reason_not_first_let property_vacancy_reason_not_first_let
property_vacancy_reason_first_let property_vacancy_reason_first_let
address_search
address
property_local_authority
local_authority_rent_value_check
property_unit_type property_unit_type
property_building_type property_building_type
property_wheelchair_accessible property_wheelchair_accessible

25
spec/models/validations/household_validations_spec.rb

@ -129,33 +129,42 @@ RSpec.describe Validations::HouseholdValidations do
context "when referral is not internal transfer" do context "when referral is not internal transfer" do
it "cannot be permanently decanted from another property owned by this landlord" do it "cannot be permanently decanted from another property owned by this landlord" do
record.reason = 1 record.reason = 1
record.referral_type = 1
record.referral = 2 record.referral = 2
household_validator.validate_reason_for_leaving_last_settled_home(record) household_validator.validate_reason_for_leaving_last_settled_home(record)
expect(record.errors["reason"]) expect(record.errors["reason"])
.to include(match(I18n.t("validations.lettings.household.reason.leaving_last_settled_home.not_internal_transfer"))) .to include(match(I18n.t("validations.lettings.household.reason.leaving_last_settled_home.not_internal_transfer")))
expect(record.errors["referral"]) expect(record.errors["referral"])
.to include(match(I18n.t("validations.lettings.household.referral.leaving_last_settled_home.reason_permanently_decanted"))) .to include(match(I18n.t("validations.lettings.household.referral.leaving_last_settled_home.reason_permanently_decanted")))
expect(record.errors["referral_type"])
.to include(match(I18n.t("validations.lettings.household.referral.leaving_last_settled_home.reason_permanently_decanted")))
end end
end end
context "when referral is internal transfer" do context "when referral is internal transfer" do
it "can be permanently decanted from another property owned by this landlord" do it "can be permanently decanted from another property owned by this landlord" do
record.reason = 1 record.reason = 1
record.referral_type = 3
record.referral = 1 record.referral = 1
household_validator.validate_reason_for_leaving_last_settled_home(record) household_validator.validate_reason_for_leaving_last_settled_home(record)
expect(record.errors["reason"]) expect(record.errors["reason"])
.to be_empty .to be_empty
expect(record.errors["referral"]) expect(record.errors["referral"])
.to be_empty .to be_empty
expect(record.errors["referral_type"])
.to be_empty
end end
it "cannot have a PRP as landlord and Housing situation before this letting cannot be LA general needs" do it "cannot have a PRP as landlord and Housing situation before this letting cannot be LA general needs" do
record.owning_organisation.provider_type = "PRP" record.owning_organisation.provider_type = "PRP"
record.prevten = 30 record.prevten = 30
record.referral_type = 3
record.referral = 1 record.referral = 1
household_validator.validate_referral(record) household_validator.validate_referral(record)
expect(record.errors["referral"]) expect(record.errors["referral"])
.to include(match(I18n.t("validations.lettings.household.referral.la_general_needs.internal_transfer"))) .to include(match(I18n.t("validations.lettings.household.referral.la_general_needs.internal_transfer")))
expect(record.errors["referral_type"])
.to include(match(I18n.t("validations.lettings.household.referral.la_general_needs.internal_transfer")))
expect(record.errors["prevten"]) expect(record.errors["prevten"])
.to include(match(I18n.t("validations.lettings.household.prevten.la_general_needs.internal_transfer"))) .to include(match(I18n.t("validations.lettings.household.prevten.la_general_needs.internal_transfer")))
@ -163,6 +172,8 @@ RSpec.describe Validations::HouseholdValidations do
household_validator.validate_referral(record) household_validator.validate_referral(record)
expect(record.errors["referral"]) expect(record.errors["referral"])
.to include(match(I18n.t("validations.lettings.household.referral.la_general_needs.internal_transfer"))) .to include(match(I18n.t("validations.lettings.household.referral.la_general_needs.internal_transfer")))
expect(record.errors["referral_type"])
.to include(match(I18n.t("validations.lettings.household.referral.la_general_needs.internal_transfer")))
expect(record.errors["prevten"]) expect(record.errors["prevten"])
.to include(match(I18n.t("validations.lettings.household.prevten.la_general_needs.internal_transfer"))) .to include(match(I18n.t("validations.lettings.household.prevten.la_general_needs.internal_transfer")))
end end
@ -603,37 +614,45 @@ RSpec.describe Validations::HouseholdValidations do
context "when homelessness is assessed" do context "when homelessness is assessed" do
it "can be internal transfer" do it "can be internal transfer" do
record.homeless = 11 record.homeless = 11
record.referral_type = 3
record.referral = 1 record.referral = 1
household_validator.validate_referral(record) household_validator.validate_referral(record)
expect(record.errors["referral"]).to be_empty expect(record.errors["referral"]).to be_empty
expect(record.errors["referral_type"]).to be_empty
expect(record.errors["homeless"]).to be_empty expect(record.errors["homeless"]).to be_empty
end end
it "can be non internal transfer" do it "can be non internal transfer" do
record.owning_organisation.provider_type = "PRP" record.owning_organisation.provider_type = "PRP"
record.homeless = 0 record.homeless = 0
record.referral_type = 2
record.referral = 3 record.referral = 3
household_validator.validate_referral(record) household_validator.validate_referral(record)
expect(record.errors["referral"]).to be_empty expect(record.errors["referral"]).to be_empty
expect(record.errors["referral_type"]).to be_empty
expect(record.errors["homeless"]).to be_empty expect(record.errors["homeless"]).to be_empty
end end
end end
context "when homelessness is other" do context "when homelessness is other" do
it "cannot be internal transfer" do it "cannot be internal transfer" do
record.referral_type = 3
record.referral = 1 record.referral = 1
record.homeless = 7 record.homeless = 7
household_validator.validate_referral(record) household_validator.validate_referral(record)
expect(record.errors["referral"]).to be_empty expect(record.errors["referral"]).to be_empty
expect(record.errors["referral_type"]).to be_empty
expect(record.errors["homeless"]).to be_empty expect(record.errors["homeless"]).to be_empty
end end
it "can be non internal transfer" do it "can be non internal transfer" do
record.owning_organisation.provider_type = "PRP" record.owning_organisation.provider_type = "PRP"
record.referral_type = 2
record.referral = 3 record.referral = 3
record.homeless = 1 record.homeless = 1
household_validator.validate_referral(record) household_validator.validate_referral(record)
expect(record.errors["referral"]).to be_empty expect(record.errors["referral"]).to be_empty
expect(record.errors["referral_type"]).to be_empty
expect(record.errors["homeless"]).to be_empty expect(record.errors["homeless"]).to be_empty
end end
end end
@ -715,6 +734,7 @@ RSpec.describe Validations::HouseholdValidations do
context "when the referral is internal transfer" do context "when the referral is internal transfer" do
it "prevten can be 9" do it "prevten can be 9" do
record.referral_type = 3
record.referral = 1 record.referral = 1
record.prevten = 9 record.prevten = 9
household_validator.validate_previous_housing_situation(record) household_validator.validate_previous_housing_situation(record)
@ -722,6 +742,8 @@ RSpec.describe Validations::HouseholdValidations do
.to be_empty .to be_empty
expect(record.errors["referral"]) expect(record.errors["referral"])
.to be_empty .to be_empty
expect(record.errors["referral_type"])
.to be_empty
end end
[ [
@ -740,6 +762,7 @@ RSpec.describe Validations::HouseholdValidations do
{ code: 29, label: "Prison or approved probation hostel" }, { code: 29, label: "Prison or approved probation hostel" },
].each do |prevten| ].each do |prevten|
it "prevten cannot be #{prevten[:code]}" do it "prevten cannot be #{prevten[:code]}" do
record.referral_type = 3
record.referral = 1 record.referral = 1
record.prevten = prevten[:code] record.prevten = prevten[:code]
household_validator.validate_previous_housing_situation(record) household_validator.validate_previous_housing_situation(record)
@ -748,6 +771,8 @@ RSpec.describe Validations::HouseholdValidations do
.to include(match I18n.t("validations.lettings.household.prevten.internal_transfer", prevten: label)) .to include(match I18n.t("validations.lettings.household.prevten.internal_transfer", prevten: label))
expect(record.errors["referral"]) expect(record.errors["referral"])
.to include(match I18n.t("validations.lettings.household.referral.prevten_invalid", prevten: "")) .to include(match I18n.t("validations.lettings.household.referral.prevten_invalid", prevten: ""))
expect(record.errors["referral_type"])
.to include(match I18n.t("validations.lettings.household.referral.prevten_invalid", prevten: ""))
end end
end end
end end

1
spec/models/validations/property_validations_spec.rb

@ -168,6 +168,7 @@ RSpec.describe Validations::PropertyValidations do
it "expects that the letting source can be a referral" do it "expects that the letting source can be a referral" do
log.prevten = 0 log.prevten = 0
log.referral_type = 1
log.referral = 2 log.referral = 2
property_validator.validate_rsnvac(log) property_validator.validate_rsnvac(log)
expect(log.errors["rsnvac"]).to be_empty expect(log.errors["rsnvac"]).to be_empty

18
spec/services/bulk_upload/lettings/year2024/row_parser_spec.rb

@ -1247,7 +1247,7 @@ RSpec.describe BulkUpload::Lettings::Year2024::RowParser do
end end
end end
context "when some reasonable preference options are seleceted" do context "when some reasonable preference options are selected" do
let(:attributes) { setup_section_params.merge({ bulk_upload:, field_106: "1", field_107: "1", field_108: nil, field_109: "1", field_110: nil, field_111: nil }) } let(:attributes) { setup_section_params.merge({ bulk_upload:, field_106: "1", field_107: "1", field_108: nil, field_109: "1", field_110: nil, field_111: nil }) }
it "sets the rest of the options to 0" do it "sets the rest of the options to 0" do
@ -1260,7 +1260,7 @@ RSpec.describe BulkUpload::Lettings::Year2024::RowParser do
end end
end end
context "when some reasonable preference options are seleceted but reasonpref is No" do context "when some reasonable preference options are selected but reasonpref is No" do
let(:attributes) { setup_section_params.merge({ bulk_upload:, field_106: "2", field_107: "1", field_108: nil, field_109: "1", field_110: nil, field_111: nil }) } let(:attributes) { setup_section_params.merge({ bulk_upload:, field_106: "2", field_107: "1", field_108: nil, field_109: "1", field_110: nil, field_111: nil }) }
it "sets the options to nil" do it "sets the options to nil" do
@ -1285,6 +1285,20 @@ RSpec.describe BulkUpload::Lettings::Year2024::RowParser do
expect(parser.errors[:field_111]).to be_present expect(parser.errors[:field_111]).to be_present
end end
end end
context "when reasonpref is Yes, some reasonable preferences are selected but also so is 'Don't know'" do
let(:attributes) { setup_section_params.merge({ bulk_upload:, field_106: "1", field_107: "1", field_108: "1", field_109: nil, field_110: nil, field_111: "1" }) }
it "is not permitted" do
parser.valid?
expect(parser.errors[:field_107]).to be_present
expect(parser.errors[:field_108]).to be_present
expect(parser.errors[:field_111]).to be_present
expect(parser.errors[:field_107]).to include(I18n.t("validations.lettings.2024.bulk_upload.reasonpref.conflict.other"))
expect(parser.errors[:field_108]).to include(I18n.t("validations.lettings.2024.bulk_upload.reasonpref.conflict.other"))
expect(parser.errors[:field_111]).to include(I18n.t("validations.lettings.2024.bulk_upload.reasonpref.conflict.dont_know"))
end
end
end end
describe "#field_116" do # referral describe "#field_116" do # referral

13
spec/services/bulk_upload/lettings/year2025/row_parser_spec.rb

@ -1096,6 +1096,19 @@ RSpec.describe BulkUpload::Lettings::Year2025::RowParser do
expect(parser.errors[:field_111]).to be_present expect(parser.errors[:field_111]).to be_present
end end
end end
context "when some reasonable preference options are selected" do
let(:attributes) { setup_section_params.merge({ bulk_upload:, field_106: "1", field_107: "1", field_108: nil, field_109: "1", field_110: nil, field_111: nil }) }
it "sets the rest of the options to 0" do
parser.valid?
expect(parser.log.rp_homeless).to eq(1)
expect(parser.log.rp_insan_unsat).to eq(0)
expect(parser.log.rp_medwel).to eq(1)
expect(parser.log.rp_hardship).to eq(0)
expect(parser.log.rp_dontknow).to eq(0)
end
end
end end
describe "#field_116" do # referral describe "#field_116" do # referral

Loading…
Cancel
Save