Browse Source

Merge branch 'main' into CLDC-3147-update-pregnancy-for-24-25

CLDC-3147-update-pregnancy-for-24-25
natdeanlewissoftwire 1 year ago
parent
commit
ce4c2ed9d7
  1. 2
      Dockerfile
  2. 4
      app/frontend/styles/_unread-notification.scss
  3. 9
      app/models/derived_variables/sales_log_variables.rb
  4. 13
      app/models/form/lettings/questions/declaration.rb
  5. 28
      app/models/form/lettings/questions/letting_allocation.rb
  6. 2
      app/models/form/lettings/questions/nationality_all_group.rb
  7. 2
      app/models/form/lettings/subsections/household_characteristics.rb
  8. 1
      app/models/form/lettings/subsections/setup.rb
  9. 17
      app/models/form/sales/pages/about_deposit_with_discount.rb
  10. 20
      app/models/form/sales/pages/about_deposit_without_discount.rb
  11. 6
      app/models/form/sales/pages/last_accommodation.rb
  12. 6
      app/models/form/sales/pages/last_accommodation_la.rb
  13. 12
      app/models/form/sales/questions/deposit_amount.rb
  14. 57
      app/models/form/sales/questions/mortgage_lender.rb
  15. 9
      app/models/form/sales/questions/nationality_all_group.rb
  16. 15
      app/models/form/sales/questions/privacy_notice.rb
  17. 2
      app/models/form/sales/subsections/discounted_ownership_scheme.rb
  18. 2
      app/models/form/sales/subsections/household_characteristics.rb
  19. 2
      app/models/form/sales/subsections/outright_sale.rb
  20. 1
      app/models/form/sales/subsections/setup.rb
  21. 8
      app/models/form/sales/subsections/shared_ownership_scheme.rb
  22. 28
      app/models/form_handler.rb
  23. 5
      app/models/sales_log.rb
  24. 2
      app/models/validations/financial_validations.rb
  25. 9
      app/models/validations/sales/household_validations.rb
  26. 1
      app/models/validations/sales/property_validations.rb
  27. 10
      app/models/validations/sales/sale_information_validations.rb
  28. 32
      app/services/bulk_upload/lettings/year2024/row_parser.rb
  29. 15
      app/services/bulk_upload/sales/year2024/row_parser.rb
  30. 2
      app/services/csv/lettings_log_csv_service.rb
  31. 2
      app/services/exports/lettings_log_export_service.rb
  32. 4
      app/views/bulk_upload_lettings_resume/deletion_report.html.erb
  33. 4
      app/views/bulk_upload_sales_resume/deletion_report.html.erb
  34. 1
      app/views/form/guidance/_privacy_notice_buyer_2024.erb
  35. 1
      app/views/form/guidance/_privacy_notice_tenant_2024.erb
  36. 2
      app/views/notifications/_notification_banner.html.erb
  37. 2
      config/locales/en.yml
  38. 5
      db/migrate/20240129161037_add_accessible_register_to_lettings_logs.rb
  39. 1
      db/schema.rb
  40. 12
      lib/tasks/clear_invalidated_earnings.rake
  41. BIN
      public/files/2024_25_sales_paper_form.pdf
  42. 1
      spec/factories/lettings_log.rb
  43. 4
      spec/fixtures/files/lettings_log_csv_export_codes_23.csv
  44. 2
      spec/fixtures/files/lettings_log_csv_export_codes_24.csv
  45. 4
      spec/fixtures/files/lettings_log_csv_export_labels_23.csv
  46. 2
      spec/fixtures/files/lettings_log_csv_export_labels_24.csv
  47. 4
      spec/fixtures/files/lettings_log_csv_export_non_support_codes_23.csv
  48. 2
      spec/fixtures/files/lettings_log_csv_export_non_support_codes_24.csv
  49. 4
      spec/fixtures/files/lettings_log_csv_export_non_support_labels_23.csv
  50. 2
      spec/fixtures/files/lettings_log_csv_export_non_support_labels_24.csv
  51. 2
      spec/fixtures/files/sales_logs_csv_export_codes_23.csv
  52. 4
      spec/fixtures/files/sales_logs_csv_export_codes_24.csv
  53. 2
      spec/fixtures/files/sales_logs_csv_export_labels_23.csv
  54. 4
      spec/fixtures/files/sales_logs_csv_export_labels_24.csv
  55. 111
      spec/lib/tasks/clear_invalidated_earnings_spec.rb
  56. 81
      spec/models/form/lettings/questions/declaration_spec.rb
  57. 74
      spec/models/form/lettings/questions/letting_allocation_spec.rb
  58. 2
      spec/models/form/lettings/questions/nationality_all_group_spec.rb
  59. 417
      spec/models/form/lettings/subsections/household_characteristics_spec.rb
  60. 62
      spec/models/form/lettings/subsections/setup_spec.rb
  61. 40
      spec/models/form/sales/pages/about_deposit_with_discount_spec.rb
  62. 44
      spec/models/form/sales/pages/about_deposit_without_discount_spec.rb
  63. 35
      spec/models/form/sales/pages/last_accommodation_la_spec.rb
  64. 33
      spec/models/form/sales/pages/last_accommodation_spec.rb
  65. 6
      spec/models/form/sales/pages/privacy_notice_spec.rb
  66. 10
      spec/models/form/sales/questions/deposit_amount_spec.rb
  67. 293
      spec/models/form/sales/questions/mortgage_lender_spec.rb
  68. 4
      spec/models/form/sales/questions/nationality_all_group_spec.rb
  69. 42
      spec/models/form/sales/questions/privacy_notice_spec.rb
  70. 1
      spec/models/form/sales/subsections/household_characteristics_spec.rb
  71. 1
      spec/models/form/sales/subsections/setup_spec.rb
  72. 4
      spec/models/form/sales/subsections/shared_ownership_scheme_spec.rb
  73. 94
      spec/models/form_handler_spec.rb
  74. 54
      spec/models/sales_log_spec.rb
  75. 21
      spec/models/validations/financial_validations_spec.rb
  76. 58
      spec/models/validations/sales/household_validations_spec.rb
  77. 12
      spec/models/validations/sales/property_validations_spec.rb
  78. 44
      spec/models/validations/sales/sale_information_validations_spec.rb
  79. 17
      spec/requests/bulk_upload_lettings_resume_controller_spec.rb
  80. 17
      spec/requests/bulk_upload_sales_resume_controller_spec.rb
  81. 9
      spec/services/bulk_upload/lettings/year2024/row_parser_spec.rb
  82. 30
      spec/services/bulk_upload/sales/year2024/row_parser_spec.rb
  83. 143
      spec/services/csv/lettings_log_csv_service_spec.rb
  84. 73
      spec/services/csv/sales_log_csv_service_spec.rb
  85. 26
      spec/services/exports/lettings_log_export_service_spec.rb

2
Dockerfile

@ -10,7 +10,7 @@ RUN apk add --update --no-cache tzdata && \
# build-base: compilation tools for bundle # build-base: compilation tools for bundle
# yarn: node package manager # yarn: node package manager
# postgresql-dev: postgres driver and libraries # postgresql-dev: postgres driver and libraries
RUN apk add --no-cache build-base=0.5-r3 nodejs-current=20.8.1-r0 yarn=1.22.19-r0 postgresql13-dev=13.13-r0 git=2.40.1-r0 bash=5.2.15-r5 RUN apk add --no-cache build-base=0.5-r3 nodejs-current=20.8.1-r0 yarn=1.22.19-r0 postgresql13-dev=13.14-r0 git=2.40.1-r0 bash=5.2.15-r5
# Bundler version should be the same version as what the Gemfile.lock was bundled with # 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.3.14 --no-document

4
app/frontend/styles/_unread-notification.scss

@ -5,3 +5,7 @@
.app-unread-notification p { .app-unread-notification p {
color: govuk-colour("white"); color: govuk-colour("white");
} }
.app-unread-notification a {
color: govuk-colour("white");
}

9
app/models/derived_variables/sales_log_variables.rb

@ -17,6 +17,15 @@ module DerivedVariables::SalesLogVariables
self.hoyear = hodate.year self.hoyear = hodate.year
end end
self.deposit = value if outright_sale? && mortgage_not_used? self.deposit = value if outright_sale? && mortgage_not_used?
if saledate && form.start_year_after_2024? && discounted_ownership_sale?
self.ppostcode_full = postcode_full
self.ppcodenk = 0 if postcode_full.present?
self.prevloc = la
self.is_previous_la_inferred = is_la_inferred
self.previous_la_known = la_known
end
self.pcode1, self.pcode2 = postcode_full.split if postcode_full.present? self.pcode1, self.pcode2 = postcode_full.split if postcode_full.present?
self.ppostc1, self.ppostc2 = ppostcode_full.split if ppostcode_full.present? self.ppostc1, self.ppostc2 = ppostcode_full.split if ppostcode_full.present?
self.totchild = total_child self.totchild = total_child

13
app/models/form/lettings/questions/declaration.rb

@ -6,10 +6,17 @@ class Form::Lettings::Questions::Declaration < ::Form::Question
@header = "Declaration" @header = "Declaration"
@type = "checkbox" @type = "checkbox"
@check_answers_card_number = 0 @check_answers_card_number = 0
@top_guidance_partial = "privacy_notice_tenant" @top_guidance_partial = form.start_year_after_2024? ? "privacy_notice_tenant_2024" : "privacy_notice_tenant"
@answer_options = ANSWER_OPTIONS
@question_number = 30 @question_number = 30
end end
ANSWER_OPTIONS = { "declaration" => { "value" => "The tenant has seen the DLUHC privacy notice" } }.freeze def answer_options
declaration_text = if form.start_year_after_2024?
"The tenant has seen or been given access to the DLUHC privacy notice"
else
"The tenant has seen the DLUHC privacy notice"
end
{ "declaration" => { "value" => declaration_text } }.freeze
end
end end

28
app/models/form/lettings/questions/letting_allocation.rb

@ -7,15 +7,27 @@ class Form::Lettings::Questions::LettingAllocation < ::Form::Question
@type = "checkbox" @type = "checkbox"
@check_answers_card_number = 0 @check_answers_card_number = 0
@hint_text = "Select all that apply." @hint_text = "Select all that apply."
@answer_options = ANSWER_OPTIONS
@question_number = 84 @question_number = 84
end end
ANSWER_OPTIONS = { def answer_options
"cbl" => { "value" => "Choice-based lettings (CBL)" }, if form.start_year_after_2024?
"cap" => { "value" => "Common Allocation Policy (CAP)" }, {
"chr" => { "value" => "Common housing register (CHR)" }, "cbl" => { "value" => "Choice-based lettings (CBL)", "hint" => "Where available vacant properties are advertised and applicants are able to bid for specific properties." },
"divider" => { "value" => true }, "cap" => { "value" => "Common Allocation Policy (CAP)", "hint" => "Where a common system agreed between a group of housing providers is used to determine applicant’s priority for housing." },
"letting_allocation_unknown" => { "value" => "None of these allocation systems" }, "chr" => { "value" => "Common housing register (CHR)", "hint" => "Where a single waiting list is used by a group of housing providers to receive and process housing applications. Providers may use different approaches to determine priority." },
}.freeze "accessible_register" => { "value" => "Accessible housing register", "hint" => "Where the ‘access category’ or another descriptor of whether an available vacant property meets a range of access needs is displayed to applicants during the allocations process." },
"divider" => { "value" => true },
"letting_allocation_unknown" => { "value" => "None of these allocation systems" },
}.freeze
else
{
"cbl" => { "value" => "Choice-based lettings (CBL)" },
"cap" => { "value" => "Common Allocation Policy (CAP)" },
"chr" => { "value" => "Common housing register (CHR)" },
"divider" => { "value" => true },
"letting_allocation_unknown" => { "value" => "None of these allocation systems" },
}.freeze
end
end
end end

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

@ -6,7 +6,7 @@ class Form::Lettings::Questions::NationalityAllGroup < ::Form::Question
@header = "What is the nationality of the lead tenant?" @header = "What is the nationality of the lead tenant?"
@type = "radio" @type = "radio"
@check_answers_card_number = 1 @check_answers_card_number = 1
@hint_text = "The lead tenant is the person in the household who does the most paid work. If several people do the same paid work, the lead tenant is whoever is the oldest." @hint_text = "The lead tenant is the person in the household who does the most paid work. If several people do the same paid work, the lead tenant is whoever is the oldest. If the lead tenant is a dual national of the United Kingdom and another country, enter United Kingdom. If they are a dual national of two other countries, the tenant should decide which country to enter."
@answer_options = ANSWER_OPTIONS @answer_options = ANSWER_OPTIONS
@question_number = 36 @question_number = 36
@conditional_for = { "nationality_all" => [12] } @conditional_for = { "nationality_all" => [12] }

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

@ -8,7 +8,7 @@ class Form::Lettings::Subsections::HouseholdCharacteristics < ::Form::Subsection
def pages def pages
@pages ||= [ @pages ||= [
Form::Lettings::Pages::Declaration.new(nil, nil, self), (Form::Lettings::Pages::Declaration.new(nil, nil, self) unless form.start_year_after_2024?),
Form::Lettings::Pages::HouseholdMembers.new(nil, nil, self), Form::Lettings::Pages::HouseholdMembers.new(nil, nil, self),
Form::Lettings::Pages::NoFemalesPregnantHouseholdLeadHhmembValueCheck.new(nil, nil, self), Form::Lettings::Pages::NoFemalesPregnantHouseholdLeadHhmembValueCheck.new(nil, nil, self),
Form::Lettings::Pages::FemalesInSoftAgeRangeInPregnantHouseholdLeadHhmembValueCheck.new(nil, nil, self), Form::Lettings::Pages::FemalesInSoftAgeRangeInPregnantHouseholdLeadHhmembValueCheck.new(nil, nil, self),

1
app/models/form/lettings/subsections/setup.rb

@ -19,6 +19,7 @@ class Form::Lettings::Subsections::Setup < ::Form::Subsection
Form::Lettings::Pages::RentType.new(nil, nil, self), Form::Lettings::Pages::RentType.new(nil, nil, self),
Form::Lettings::Pages::TenantCode.new(nil, nil, self), Form::Lettings::Pages::TenantCode.new(nil, nil, self),
Form::Lettings::Pages::PropertyReference.new(nil, nil, self), Form::Lettings::Pages::PropertyReference.new(nil, nil, self),
(Form::Lettings::Pages::Declaration.new(nil, nil, self) if form.start_year_after_2024?),
].compact ].compact
end end

17
app/models/form/sales/pages/about_deposit_with_discount.rb

@ -1,15 +1,22 @@
class Form::Sales::Pages::AboutDepositWithDiscount < ::Form::Page class Form::Sales::Pages::AboutDepositWithDiscount < ::Form::Page
def initialize(id, hsh, subsection) def initialize(id, hsh, subsection, optional:)
super super(id, hsh, subsection)
@id = "about_deposit_with_discount"
@header = "About the deposit" @header = "About the deposit"
@depends_on = [{ "is_type_discount?" => true }] @optional = optional
end end
def questions def questions
@questions ||= [ @questions ||= [
Form::Sales::Questions::DepositAmount.new(nil, nil, self, ownershipsch: 1), Form::Sales::Questions::DepositAmount.new(nil, nil, self, ownershipsch: 1, optional: @optional),
Form::Sales::Questions::DepositDiscount.new(nil, nil, self), Form::Sales::Questions::DepositDiscount.new(nil, nil, self),
] ]
end end
def depends_on
if form.start_year_after_2024?
[{ "is_type_discount?" => true, "stairowned_100?" => @optional }]
else
[{ "is_type_discount?" => true }]
end
end
end end

20
app/models/form/sales/pages/about_deposit_without_discount.rb

@ -1,16 +1,26 @@
class Form::Sales::Pages::AboutDepositWithoutDiscount < ::Form::Page class Form::Sales::Pages::AboutDepositWithoutDiscount < ::Form::Page
def initialize(id, hsh, subsection, ownershipsch:) def initialize(id, hsh, subsection, ownershipsch:, optional:)
super(id, hsh, subsection) super(id, hsh, subsection)
@header = "About the deposit" @header = "About the deposit"
@depends_on = [{ "is_type_discount?" => false, "ownershipsch" => 1 },
{ "ownershipsch" => 2 },
{ "ownershipsch" => 3, "mortgageused" => 1 }]
@ownershipsch = ownershipsch @ownershipsch = ownershipsch
@optional = optional
end end
def questions def questions
@questions ||= [ @questions ||= [
Form::Sales::Questions::DepositAmount.new(nil, nil, self, ownershipsch: @ownershipsch), Form::Sales::Questions::DepositAmount.new(nil, nil, self, ownershipsch: @ownershipsch, optional: @optional),
] ]
end end
def depends_on
if form.start_year_after_2024?
[{ "is_type_discount?" => false, "ownershipsch" => 1, "stairowned_100?" => @optional },
{ "ownershipsch" => 2 },
{ "ownershipsch" => 3, "mortgageused" => 1 }]
else
[{ "is_type_discount?" => false, "ownershipsch" => 1 },
{ "ownershipsch" => 2 },
{ "ownershipsch" => 3, "mortgageused" => 1 }]
end
end
end end

6
app/models/form/sales/pages/last_accommodation.rb

@ -10,4 +10,10 @@ class Form::Sales::Pages::LastAccommodation < ::Form::Page
Form::Sales::Questions::PreviousPostcode.new(nil, nil, self), Form::Sales::Questions::PreviousPostcode.new(nil, nil, self),
] ]
end end
def routed_to?(log, _user)
return false if log.form.start_year_after_2024? && log.discounted_ownership_sale?
super
end
end end

6
app/models/form/sales/pages/last_accommodation_la.rb

@ -13,4 +13,10 @@ class Form::Sales::Pages::LastAccommodationLa < ::Form::Page
Form::Sales::Questions::Prevloc.new(nil, nil, self), Form::Sales::Questions::Prevloc.new(nil, nil, self),
] ]
end end
def routed_to?(log, _user)
return false if log.form.start_year_after_2024? && log.discounted_ownership_sale?
super
end
end end

12
app/models/form/sales/questions/deposit_amount.rb

@ -1,5 +1,5 @@
class Form::Sales::Questions::DepositAmount < ::Form::Question class Form::Sales::Questions::DepositAmount < ::Form::Question
def initialize(id, hsh, subsection, ownershipsch:) def initialize(id, hsh, subsection, ownershipsch:, optional:)
super(id, hsh, subsection) super(id, hsh, subsection)
@id = "deposit" @id = "deposit"
@check_answer_label = "Cash deposit" @check_answer_label = "Cash deposit"
@ -10,10 +10,10 @@ class Form::Sales::Questions::DepositAmount < ::Form::Question
@step = 1 @step = 1
@width = 5 @width = 5
@prefix = "£" @prefix = "£"
@hint_text = "Enter the total cash sum paid by the buyer towards the property that was not funded by the mortgage"
@derived = true @derived = true
@ownershipsch = ownershipsch @ownershipsch = ownershipsch
@question_number = question_number @question_number = question_number
@optional = optional
end end
def selected_answer_option_is_derived?(_log) def selected_answer_option_is_derived?(_log)
@ -30,4 +30,12 @@ class Form::Sales::Questions::DepositAmount < ::Form::Question
116 116
end end
end end
def hint_text
if @optional
"Enter the total cash sum paid by the buyer towards the property that was not funded by the mortgage. As this is a fully staircased sale this question is optional. If you do not have the information available click save and continue"
else
"Enter the total cash sum paid by the buyer towards the property that was not funded by the mortgage"
end
end
end end

57
app/models/form/sales/questions/mortgage_lender.rb

@ -7,7 +7,6 @@ class Form::Sales::Questions::MortgageLender < ::Form::Question
@type = "select" @type = "select"
@hint_text = "" @hint_text = ""
@page = page @page = page
@answer_options = ANSWER_OPTIONS
@bottom_guidance_partial = "mortgage_lender" @bottom_guidance_partial = "mortgage_lender"
@ownershipsch = ownershipsch @ownershipsch = ownershipsch
@question_number = question_number @question_number = question_number
@ -54,54 +53,24 @@ class Form::Sales::Questions::MortgageLender < ::Form::Question
"37" => "Virgin Money", "37" => "Virgin Money",
"38" => "West Bromwich Building Society", "38" => "West Bromwich Building Society",
"39" => "Yorkshire Building Society", "39" => "Yorkshire Building Society",
"41" => "Kent Reliance",
"40" => "Other", "40" => "Other",
"0" => "Don’t know", "0" => "Don’t know",
}.freeze }.freeze
OPTIONS_INTRODUCED_2024 = %w[41].freeze
OPTIONS_NOT_DISPLAYED = %w[0].freeze
def answer_options
if form.start_year_after_2024?
ANSWER_OPTIONS
else
ANSWER_OPTIONS.dup.reject { |k, _v| OPTIONS_INTRODUCED_2024.include?(k) }
end
end
def displayed_answer_options(_log, _user = nil) def displayed_answer_options(_log, _user = nil)
{ answer_options.reject { |k, _v| OPTIONS_NOT_DISPLAYED.include?(k) }
"" => "Select an option",
"1" => "Atom Bank",
"2" => "Barclays Bank PLC",
"3" => "Bath Building Society",
"4" => "Buckinghamshire Building Society",
"5" => "Cambridge Building Society",
"6" => "Coventry Building Society",
"7" => "Cumberland Building Society",
"8" => "Darlington Building Society",
"9" => "Dudley Building Society",
"10" => "Ecology Building Society",
"11" => "Halifax",
"12" => "Hanley Economic Building Society",
"13" => "Hinckley and Rugby Building Society",
"14" => "Holmesdale Building Society",
"15" => "Ipswich Building Society",
"16" => "Leeds Building Society",
"17" => "Lloyds Bank",
"18" => "Mansfield Building Society",
"19" => "Market Harborough Building Society",
"20" => "Melton Mowbray Building Society",
"21" => "Nationwide Building Society",
"22" => "Natwest",
"23" => "Nedbank Private Wealth",
"24" => "Newbury Building Society",
"25" => "OneSavings Bank",
"26" => "Parity Trust",
"27" => "Penrith Building Society",
"28" => "Pepper Homeloans",
"29" => "Royal Bank of Scotland",
"30" => "Santander",
"31" => "Skipton Building Society",
"32" => "Teachers Building Society",
"33" => "The Co-operative Bank",
"34" => "Tipton & Coseley Building Society",
"35" => "TSB",
"36" => "Ulster Bank",
"37" => "Virgin Money",
"38" => "West Bromwich Building Society",
"39" => "Yorkshire Building Society",
"40" => "Other",
}
end end
def question_number def question_number

9
app/models/form/sales/questions/nationality_all_group.rb

@ -10,6 +10,7 @@ class Form::Sales::Questions::NationalityAllGroup < ::Form::Question
@question_number = buyer_index == 1 ? 24 : 32 @question_number = buyer_index == 1 ? 24 : 32
@conditional_for = buyer_index == 1 ? { "nationality_all" => [12] } : { "nationality_all_buyer2" => [12] } @conditional_for = buyer_index == 1 ? { "nationality_all" => [12] } : { "nationality_all_buyer2" => [12] }
@hidden_in_check_answers = { "depends_on" => [{ id => 12 }] } @hidden_in_check_answers = { "depends_on" => [{ id => 12 }] }
@buyer_index = buyer_index
end end
ANSWER_OPTIONS = { ANSWER_OPTIONS = {
@ -17,4 +18,12 @@ class Form::Sales::Questions::NationalityAllGroup < ::Form::Question
"12" => { "value" => "Other" }, "12" => { "value" => "Other" },
"0" => { "value" => "Buyer prefers not to say" }, "0" => { "value" => "Buyer prefers not to say" },
}.freeze }.freeze
def hint_text
if @buyer_index == 1
"Buyer 1 is the person in the household who does the most paid work. If it’s a joint purchase and the buyers do the same amount of paid work, buyer 1 is whoever is the oldest. If buyer 1 is a dual national of the United Kingdom and another country, enter United Kingdom. If they are a dual national of two other countries, the buyer should decide which country to enter."
else
"If buyer 2 is a dual national of the United Kingdom and another country, enter United Kingdom. If they are a dual national of two other countries, the buyer should decide which country to enter."
end
end
end end

15
app/models/form/sales/questions/privacy_notice.rb

@ -5,12 +5,17 @@ class Form::Sales::Questions::PrivacyNotice < ::Form::Question
@check_answer_label = "Buyer has seen the privacy notice?" @check_answer_label = "Buyer has seen the privacy notice?"
@header = "Declaration" @header = "Declaration"
@type = "checkbox" @type = "checkbox"
@answer_options = ANSWER_OPTIONS @top_guidance_partial = form.start_year_after_2024? ? "privacy_notice_buyer_2024" : "privacy_notice_buyer"
@top_guidance_partial = "privacy_notice_buyer"
@question_number = 19 @question_number = 19
end end
ANSWER_OPTIONS = { def answer_options
"privacynotice" => { "value" => "The buyer has seen the DLUHC privacy notice" }, declaration_text = if form.start_year_after_2024?
}.freeze "The buyer has seen or been given access to the DLUHC privacy notice"
else
"The buyer has seen the DLUHC privacy notice"
end
{ "privacynotice" => { "value" => declaration_text } }.freeze
end
end end

2
app/models/form/sales/subsections/discounted_ownership_scheme.rb

@ -31,7 +31,7 @@ class Form::Sales::Subsections::DiscountedOwnershipScheme < ::Form::Subsection
Form::Sales::Pages::MortgageLength.new("mortgage_length_discounted_ownership", nil, self, ownershipsch: 2), Form::Sales::Pages::MortgageLength.new("mortgage_length_discounted_ownership", nil, self, ownershipsch: 2),
Form::Sales::Pages::ExtraBorrowing.new("extra_borrowing_discounted_ownership", nil, self, ownershipsch: 2), Form::Sales::Pages::ExtraBorrowing.new("extra_borrowing_discounted_ownership", nil, self, ownershipsch: 2),
Form::Sales::Pages::ExtraBorrowingValueCheck.new("extra_borrowing_value_check", nil, self), Form::Sales::Pages::ExtraBorrowingValueCheck.new("extra_borrowing_value_check", nil, self),
Form::Sales::Pages::AboutDepositWithoutDiscount.new("about_deposit_discounted_ownership", nil, self, ownershipsch: 2), Form::Sales::Pages::AboutDepositWithoutDiscount.new("about_deposit_discounted_ownership", nil, self, ownershipsch: 2, optional: false),
Form::Sales::Pages::ExtraBorrowingValueCheck.new("extra_borrowing_deposit_value_check", nil, self), Form::Sales::Pages::ExtraBorrowingValueCheck.new("extra_borrowing_deposit_value_check", nil, self),
Form::Sales::Pages::DepositValueCheck.new("discounted_ownership_deposit_value_check", nil, self), Form::Sales::Pages::DepositValueCheck.new("discounted_ownership_deposit_value_check", nil, self),
Form::Sales::Pages::DepositAndMortgageValueCheck.new("discounted_ownership_deposit_and_mortgage_value_check_after_deposit", nil, self), Form::Sales::Pages::DepositAndMortgageValueCheck.new("discounted_ownership_deposit_and_mortgage_value_check_after_deposit", nil, self),

2
app/models/form/sales/subsections/household_characteristics.rb

@ -9,7 +9,7 @@ class Form::Sales::Subsections::HouseholdCharacteristics < ::Form::Subsection
def pages def pages
@pages ||= [ @pages ||= [
(Form::Sales::Pages::BuyerInterview.new(nil, nil, self) unless form.start_year_after_2024?), (Form::Sales::Pages::BuyerInterview.new(nil, nil, self) unless form.start_year_after_2024?),
Form::Sales::Pages::PrivacyNotice.new(nil, nil, self), (Form::Sales::Pages::PrivacyNotice.new(nil, nil, self) unless form.start_year_after_2024?),
Form::Sales::Pages::Age1.new(nil, nil, self), Form::Sales::Pages::Age1.new(nil, nil, self),
Form::Sales::Pages::RetirementValueCheck.new("age_1_retirement_value_check", nil, self, person_index: 1), Form::Sales::Pages::RetirementValueCheck.new("age_1_retirement_value_check", nil, self, person_index: 1),
Form::Sales::Pages::OldPersonsSharedOwnershipValueCheck.new("age_1_old_persons_shared_ownership_value_check", nil, self), Form::Sales::Pages::OldPersonsSharedOwnershipValueCheck.new("age_1_old_persons_shared_ownership_value_check", nil, self),

2
app/models/form/sales/subsections/outright_sale.rb

@ -18,7 +18,7 @@ class Form::Sales::Subsections::OutrightSale < ::Form::Subsection
(Form::Sales::Pages::MortgageLenderOther.new("mortgage_lender_other_outright_sale", nil, self, ownershipsch: 3) unless form.start_year_after_2024?), (Form::Sales::Pages::MortgageLenderOther.new("mortgage_lender_other_outright_sale", nil, self, ownershipsch: 3) unless form.start_year_after_2024?),
Form::Sales::Pages::MortgageLength.new("mortgage_length_outright_sale", nil, self, ownershipsch: 3), Form::Sales::Pages::MortgageLength.new("mortgage_length_outright_sale", nil, self, ownershipsch: 3),
Form::Sales::Pages::ExtraBorrowing.new("extra_borrowing_outright_sale", nil, self, ownershipsch: 3), Form::Sales::Pages::ExtraBorrowing.new("extra_borrowing_outright_sale", nil, self, ownershipsch: 3),
Form::Sales::Pages::AboutDepositWithoutDiscount.new("about_deposit_outright_sale", nil, self, ownershipsch: 3), Form::Sales::Pages::AboutDepositWithoutDiscount.new("about_deposit_outright_sale", nil, self, ownershipsch: 3, optional: false),
Form::Sales::Pages::DepositValueCheck.new("outright_sale_deposit_value_check", nil, self), Form::Sales::Pages::DepositValueCheck.new("outright_sale_deposit_value_check", nil, self),
leasehold_charge_pages, leasehold_charge_pages,
Form::Sales::Pages::MonthlyChargesValueCheck.new("monthly_charges_outright_sale_value_check", nil, self), Form::Sales::Pages::MonthlyChargesValueCheck.new("monthly_charges_outright_sale_value_check", nil, self),

1
app/models/form/sales/subsections/setup.rb

@ -21,6 +21,7 @@ class Form::Sales::Subsections::Setup < ::Form::Subsection
Form::Sales::Pages::JointPurchase.new(nil, nil, self), Form::Sales::Pages::JointPurchase.new(nil, nil, self),
Form::Sales::Pages::NumberJointBuyers.new(nil, nil, self), Form::Sales::Pages::NumberJointBuyers.new(nil, nil, self),
(Form::Sales::Pages::BuyerInterview.new(nil, nil, self) if form.start_year_after_2024?), (Form::Sales::Pages::BuyerInterview.new(nil, nil, self) if form.start_year_after_2024?),
(Form::Sales::Pages::PrivacyNotice.new(nil, nil, self) if form.start_year_after_2024?),
].flatten.compact ].flatten.compact
end end
end end

8
app/models/form/sales/subsections/shared_ownership_scheme.rb

@ -37,14 +37,16 @@ class Form::Sales::Subsections::SharedOwnershipScheme < ::Form::Subsection
Form::Sales::Pages::MortgageLenderOther.new("mortgage_lender_other_shared_ownership", nil, self, ownershipsch: 1), Form::Sales::Pages::MortgageLenderOther.new("mortgage_lender_other_shared_ownership", nil, self, ownershipsch: 1),
Form::Sales::Pages::MortgageLength.new("mortgage_length_shared_ownership", nil, self, ownershipsch: 1), Form::Sales::Pages::MortgageLength.new("mortgage_length_shared_ownership", nil, self, ownershipsch: 1),
Form::Sales::Pages::ExtraBorrowing.new("extra_borrowing_shared_ownership", nil, self, ownershipsch: 1), Form::Sales::Pages::ExtraBorrowing.new("extra_borrowing_shared_ownership", nil, self, ownershipsch: 1),
Form::Sales::Pages::AboutDepositWithDiscount.new(nil, nil, self), Form::Sales::Pages::AboutDepositWithDiscount.new("about_deposit_with_discount", nil, self, optional: false),
Form::Sales::Pages::AboutDepositWithoutDiscount.new("about_deposit_shared_ownership", nil, self, ownershipsch: 1), (Form::Sales::Pages::AboutDepositWithDiscount.new("about_deposit_with_discount_optional", nil, self, optional: true) if form.start_year_after_2024?),
Form::Sales::Pages::AboutDepositWithoutDiscount.new("about_deposit_shared_ownership", nil, self, ownershipsch: 1, optional: false),
(Form::Sales::Pages::AboutDepositWithoutDiscount.new("about_deposit_shared_ownership_optional", nil, self, ownershipsch: 1, optional: true) if form.start_year_after_2024?),
Form::Sales::Pages::DepositValueCheck.new("deposit_value_check", nil, self), Form::Sales::Pages::DepositValueCheck.new("deposit_value_check", nil, self),
Form::Sales::Pages::SharedOwnershipDepositValueCheck.new("shared_ownership_deposit_value_check", nil, self), Form::Sales::Pages::SharedOwnershipDepositValueCheck.new("shared_ownership_deposit_value_check", nil, self),
Form::Sales::Pages::MonthlyRent.new(nil, nil, self), Form::Sales::Pages::MonthlyRent.new(nil, nil, self),
Form::Sales::Pages::LeaseholdCharges.new("leasehold_charges_shared_ownership", nil, self, ownershipsch: 1), Form::Sales::Pages::LeaseholdCharges.new("leasehold_charges_shared_ownership", nil, self, ownershipsch: 1),
Form::Sales::Pages::MonthlyChargesValueCheck.new("monthly_charges_shared_ownership_value_check", nil, self), Form::Sales::Pages::MonthlyChargesValueCheck.new("monthly_charges_shared_ownership_value_check", nil, self),
] ].compact
end end
def displayed_in_tasklist?(log) def displayed_in_tasklist?(log)

28
app/models/form_handler.rb

@ -50,11 +50,10 @@ class FormHandler
end end
def ordered_sales_questions_for_all_years def ordered_sales_questions_for_all_years
sales_forms = forms.filter { |name, _form| name.end_with? "sales" }.values ordered_questions = current_sales_form.questions.uniq(&:id)
ordered_questions = sales_forms.pop.questions.uniq(&:id) all_sales_forms = forms.filter { |name, _form| name.end_with? "sales" }.values
question_ids = ordered_questions.map(&:id) all_questions_from_available_sales_forms = all_sales_forms.flat_map(&:questions)
all_questions_from_previous_forms = sales_forms.flat_map(&:questions) deprecated_questions_by_preceding_question_id(ordered_questions, all_questions_from_available_sales_forms).each do |preceding_question_id, deprecated_question|
deprecated_questions_by_preceding_question_id(question_ids, all_questions_from_previous_forms).each do |preceding_question_id, deprecated_question|
index_of_preceding_question = ordered_questions.index { |q| q.id == preceding_question_id } index_of_preceding_question = ordered_questions.index { |q| q.id == preceding_question_id }
ordered_questions.insert(index_of_preceding_question + 1, deprecated_question) ordered_questions.insert(index_of_preceding_question + 1, deprecated_question)
end end
@ -62,23 +61,28 @@ class FormHandler
end end
def ordered_lettings_questions_for_all_years def ordered_lettings_questions_for_all_years
lettings_forms = forms.filter { |name, _form| name.end_with? "lettings" }.values ordered_questions = current_lettings_form.questions.uniq(&:id)
ordered_questions = lettings_forms.pop.questions.uniq(&:id) all_lettings_forms = forms.filter { |name, _form| name.end_with? "lettings" }.values
question_ids = ordered_questions.map(&:id) all_questions_from_available_lettings_forms = all_lettings_forms.flat_map(&:questions)
all_questions_from_previous_forms = lettings_forms.flat_map(&:questions) deprecated_questions_by_preceding_question_id(ordered_questions, all_questions_from_available_lettings_forms).each do |preceding_question_id, deprecated_question|
deprecated_questions_by_preceding_question_id(question_ids, all_questions_from_previous_forms).each do |preceding_question_id, deprecated_question|
index_of_preceding_question = ordered_questions.index { |q| q.id == preceding_question_id } index_of_preceding_question = ordered_questions.index { |q| q.id == preceding_question_id }
ordered_questions.insert(index_of_preceding_question + 1, deprecated_question) ordered_questions.insert(index_of_preceding_question + 1, deprecated_question)
end end
ordered_questions ordered_questions
end end
def deprecated_questions_by_preceding_question_id(current_form_question_ids, all_questions_from_previous_forms) def deprecated_questions_by_preceding_question_id(current_form_questions, all_questions_from_previous_forms)
current_form_question_ids = current_form_questions.map(&:id)
deprecated_questions = {} deprecated_questions = {}
all_questions_from_previous_forms.each_cons(2) do |preceding_question, question| all_questions_from_previous_forms.each_cons(2) do |preceding_question, question|
next if current_form_question_ids.include?(question.id) || deprecated_questions.values.map(&:id).include?(question.id) next if current_form_question_ids.include?(question.id) || deprecated_questions.values.map(&:id).include?(question.id)
deprecated_questions[preceding_question.id] = question if question.subsection.id == preceding_question.subsection.id
deprecated_questions[preceding_question.id] = question
else
last_in_preceding_subsection = current_form_questions.rindex { |q| q.subsection.id == preceding_question.subsection.id }
deprecated_questions[current_form_questions[last_in_preceding_subsection].id] = question
end
end end
deprecated_questions deprecated_questions
end end

5
app/models/sales_log.rb

@ -121,6 +121,7 @@ class SalesLog < Log
not_required << "proplen" if proplen_optional? not_required << "proplen" if proplen_optional?
not_required << "mortlen" if mortlen_optional? not_required << "mortlen" if mortlen_optional?
not_required << "frombeds" if frombeds_optional? not_required << "frombeds" if frombeds_optional?
not_required << "deposit" if form.start_year_after_2024? && stairowned_100?
not_required |= %w[address_line2 county postcode_full] if saledate && collection_start_year_for_date(saledate) >= 2023 not_required |= %w[address_line2 county postcode_full] if saledate && collection_start_year_for_date(saledate) >= 2023
@ -495,4 +496,8 @@ class SalesLog < Log
def is_not_staircasing? def is_not_staircasing?
staircase == 2 || staircase == 3 staircase == 2 || staircase == 3
end end
def stairowned_100?
stairowned == 100
end
end end

2
app/models/validations/financial_validations.rb

@ -24,7 +24,7 @@ module Validations::FinancialValidations
end end
def validate_net_income(record) def validate_net_income(record)
if record.ecstat1 && record.hhmemb && record.weekly_net_income if record.ecstat1 && record.hhmemb && record.weekly_net_income && record.startdate && record.form.start_date.year >= 2023
if record.weekly_net_income > record.applicable_income_range.hard_max if record.weekly_net_income > record.applicable_income_range.hard_max
frequency = record.form.get_question("incfreq", record).label_from_value(record.incfreq).downcase frequency = record.form.get_question("incfreq", record).label_from_value(record.incfreq).downcase
hard_max = format_as_currency(record.applicable_income_range.hard_max) hard_max = format_as_currency(record.applicable_income_range.hard_max)

9
app/models/validations/sales/household_validations.rb

@ -11,15 +11,6 @@ module Validations::Sales::HouseholdValidations
shared_validate_partner_count(record, 6) shared_validate_partner_count(record, 6)
end end
def validate_previous_postcode(record)
return unless record.postcode_full && record.ppostcode_full && record.discounted_ownership_sale?
unless record.postcode_full == record.ppostcode_full
record.errors.add :postcode_full, :postcodes_not_matching, message: I18n.t("validations.household.postcode.discounted_ownership")
record.errors.add :ppostcode_full, :postcodes_not_matching, message: I18n.t("validations.household.postcode.discounted_ownership")
end
end
def validate_buyers_living_in_property(record) def validate_buyers_living_in_property(record)
return unless record.form.start_date.year >= 2023 return unless record.form.start_date.year >= 2023

1
app/models/validations/sales/property_validations.rb

@ -1,5 +1,6 @@
module Validations::Sales::PropertyValidations module Validations::Sales::PropertyValidations
def validate_postcodes_match_if_discounted_ownership(record) def validate_postcodes_match_if_discounted_ownership(record)
return unless record.saledate && !record.form.start_year_after_2024?
return unless record.ppostcode_full.present? && record.postcode_full.present? return unless record.ppostcode_full.present? && record.postcode_full.present?
if record.discounted_ownership_sale? && record.ppostcode_full != record.postcode_full if record.discounted_ownership_sale? && record.ppostcode_full != record.postcode_full

10
app/models/validations/sales/sale_information_validations.rb

@ -110,4 +110,14 @@ module Validations::Sales::SaleInformationValidations
end end
end end
end end
def validate_mortgage_used_and_stairbought(record)
return unless record.stairowned && record.mortgageused
return unless record.saledate && record.form.start_year_after_2024?
if !record.stairowned_100? && record.mortgageused == 3
record.errors.add :stairowned, I18n.t("validations.sale_information.stairowned.mortgageused_dont_know")
record.errors.add :mortgageused, I18n.t("validations.sale_information.stairowned.mortgageused_dont_know")
end
end
end end

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

@ -377,8 +377,6 @@ class BulkUpload::Lettings::Year2024::RowParser
validate :validate_created_by_exists, on: :after_log validate :validate_created_by_exists, on: :after_log
validate :validate_created_by_related, on: :after_log validate :validate_created_by_related, on: :after_log
validate :validate_declaration_acceptance, on: :after_log
validate :validate_nulls, on: :after_log validate :validate_nulls, on: :after_log
validate :validate_uprn_exists_if_any_key_address_fields_are_blank, on: :after_log, unless: -> { supported_housing? } validate :validate_uprn_exists_if_any_key_address_fields_are_blank, on: :after_log, unless: -> { supported_housing? }
@ -494,12 +492,6 @@ class BulkUpload::Lettings::Year2024::RowParser
private private
def validate_declaration_acceptance
unless field_15 == 1
errors.add(:field_15, I18n.t("validations.declaration.missing"), category: :setup)
end
end
def validate_valid_radio_option def validate_valid_radio_option
log.attributes.each do |question_id, _v| log.attributes.each do |question_id, _v|
question = log.form.get_question(question_id, log) question = log.form.get_question(question_id, log)
@ -659,10 +651,11 @@ private
end end
def validate_lettings_allocation def validate_lettings_allocation
if cbl.blank? && cap.blank? && chr.blank? if cbl.blank? && cap.blank? && chr.blank? && accessible_register.blank?
errors.add(:field_112, I18n.t("validations.not_answered", question: "was the letting made under the Choice-Based Lettings (CBL)?")) errors.add(:field_112, I18n.t("validations.not_answered", question: "was the letting made under the Choice-Based Lettings (CBL)?"))
errors.add(:field_113, I18n.t("validations.not_answered", question: "was the letting made under the Common Allocation Policy (CAP)?")) errors.add(:field_113, I18n.t("validations.not_answered", question: "was the letting made under the Common Allocation Policy (CAP)?"))
errors.add(:field_114, I18n.t("validations.not_answered", question: "was the letting made under the Common Housing Register (CHR)?")) errors.add(:field_114, I18n.t("validations.not_answered", question: "was the letting made under the Common Housing Register (CHR)?"))
errors.add(:field_115, I18n.t("validations.not_answered", question: "was the letting made under the Accessible Register?"))
end end
end end
@ -953,9 +946,10 @@ private
rp_dontknow: %i[field_111], rp_dontknow: %i[field_111],
cbl: %i[field_112], cbl: %i[field_112],
chr: %i[field_114],
cap: %i[field_113], cap: %i[field_113],
letting_allocation: %i[field_112 field_113 field_114], chr: %i[field_114],
accessible_register: %i[field_115],
letting_allocation: %i[field_112 field_113 field_114 field_115],
referral: %i[field_116], referral: %i[field_116],
@ -1141,6 +1135,7 @@ private
attributes["cbl"] = cbl attributes["cbl"] = cbl
attributes["chr"] = chr attributes["chr"] = chr
attributes["cap"] = cap attributes["cap"] = cap
attributes["accessible_register"] = accessible_register
attributes["letting_allocation_unknown"] = letting_allocation_unknown attributes["letting_allocation_unknown"] = letting_allocation_unknown
attributes["referral"] = field_116 attributes["referral"] = field_116
@ -1390,6 +1385,15 @@ private
end end
end end
def cap
case field_113
when 2
0
when 1
1
end
end
def chr def chr
case field_114 case field_114
when 2 when 2
@ -1399,8 +1403,8 @@ private
end end
end end
def cap def accessible_register
case field_113 case field_115
when 2 when 2
0 0
when 1 when 1
@ -1409,7 +1413,7 @@ private
end end
def letting_allocation_unknown def letting_allocation_unknown
[cbl, chr, cap].all?(0) ? 1 : 0 [cbl, chr, cap, accessible_register].all?(0) ? 1 : 0
end end
def net_income_known def net_income_known

15
app/services/bulk_upload/sales/year2024/row_parser.rb

@ -341,6 +341,14 @@ class BulkUpload::Sales::Year2024::RowParser
}, },
on: :before_log on: :before_log
validates :field_103,
inclusion: {
in: [1, 2],
if: proc { field_88 != 100 },
question: QUESTIONS[:field_103],
},
on: :before_log
validates :field_9, validates :field_9,
presence: { presence: {
message: I18n.t("validations.not_answered", question: "type of shared ownership sale"), message: I18n.t("validations.not_answered", question: "type of shared ownership sale"),
@ -460,7 +468,6 @@ class BulkUpload::Sales::Year2024::RowParser
validate :validate_address_fields, on: :after_log validate :validate_address_fields, 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? }
validate :validate_data_protection_answered, on: :after_log
validate :validate_buyers_organisations, on: :after_log validate :validate_buyers_organisations, on: :after_log
def self.question_for_field(field) def self.question_for_field(field)
@ -557,12 +564,6 @@ class BulkUpload::Sales::Year2024::RowParser
private private
def validate_data_protection_answered
unless field_18 == 1
errors.add(:field_18, I18n.t("validations.not_answered", question: QUESTIONS[:field_18].downcase), category: :setup)
end
end
def validate_buyers_organisations def validate_buyers_organisations
organisations_fields = %i[field_66 field_67 field_68 field_69] organisations_fields = %i[field_66 field_67 field_68 field_69]
if organisations_fields.all? { |field| attributes[field.to_s].blank? } if organisations_fields.all? { |field| attributes[field.to_s].blank? }

2
app/services/csv/lettings_log_csv_service.rb

@ -263,7 +263,7 @@ module Csv
"renttype" => RENTTYPE_LABELS, "renttype" => RENTTYPE_LABELS,
}.freeze }.freeze
CONVENTIONAL_YES_NO_ATTRIBUTES = %w[illness_type_1 illness_type_2 illness_type_3 illness_type_4 illness_type_5 illness_type_6 illness_type_7 illness_type_8 illness_type_9 illness_type_10 refused cbl cap chr letting_allocation_none housingneeds_a housingneeds_b housingneeds_c housingneeds_d housingneeds_e housingneeds_f housingneeds_g housingneeds_h has_benefits nocharge postcode_known].freeze CONVENTIONAL_YES_NO_ATTRIBUTES = %w[illness_type_1 illness_type_2 illness_type_3 illness_type_4 illness_type_5 illness_type_6 illness_type_7 illness_type_8 illness_type_9 illness_type_10 refused cbl cap chr accessible_register letting_allocation_none housingneeds_a housingneeds_b housingneeds_c housingneeds_d housingneeds_e housingneeds_f housingneeds_g housingneeds_h has_benefits nocharge postcode_known].freeze
YES_OR_BLANK_ATTRIBUTES = %w[declaration rp_homeless rp_insan_unsat rp_medwel rp_hardship rp_dontknow].freeze YES_OR_BLANK_ATTRIBUTES = %w[declaration rp_homeless rp_insan_unsat rp_medwel rp_hardship rp_dontknow].freeze

2
app/services/exports/lettings_log_export_service.rb

@ -12,9 +12,9 @@ module Exports
start_time = Time.zone.now start_time = Time.zone.now
daily_run_number = get_daily_run_number daily_run_number = get_daily_run_number
archives_for_manifest = {} archives_for_manifest = {}
base_number = LogsExport.where(empty_export: false).maximum(:base_number) || 1
recent_export = LogsExport.order("started_at").last recent_export = LogsExport.order("started_at").last
collection_years_to_export(collection_year).each do |collection| collection_years_to_export(collection_year).each do |collection|
base_number = LogsExport.where(empty_export: false, collection:).maximum(:base_number) || 1
export = build_export_run(collection, start_time, base_number, full_update) export = build_export_run(collection, start_time, base_number, full_update)
archives = write_export_archive(export, collection, start_time, recent_export, full_update) archives = write_export_archive(export, collection, start_time, recent_export, full_update)

4
app/views/bulk_upload_lettings_resume/deletion_report.html.erb

@ -18,7 +18,9 @@
<div class="govuk-grid-row"> <div class="govuk-grid-row">
<div class="govuk-grid-column-full"> <div class="govuk-grid-column-full">
<% @bulk_upload.bulk_upload_errors.order_by_row.order_by_cell.group_by(&:row).each do |_row, errors_for_row| %> <% @bulk_upload.bulk_upload_errors.order_by_row.order_by_cell.group_by(&:row).each do |_row, errors_for_row| %>
<%= render BulkUploadErrorRowComponent.new(bulk_upload_errors: all_answers_to_be_cleared(errors_for_row)) %> <% if all_answers_to_be_cleared(errors_for_row).present? %>
<%= render BulkUploadErrorRowComponent.new(bulk_upload_errors: all_answers_to_be_cleared(errors_for_row)) %>
<% end %>
<% end %> <% end %>
</div> </div>
</div> </div>

4
app/views/bulk_upload_sales_resume/deletion_report.html.erb

@ -18,7 +18,9 @@
<div class="govuk-grid-row"> <div class="govuk-grid-row">
<div class="govuk-grid-column-full"> <div class="govuk-grid-column-full">
<% @bulk_upload.bulk_upload_errors.order_by_row.order_by_cell.group_by(&:row).each do |_row, errors_for_row| %> <% @bulk_upload.bulk_upload_errors.order_by_row.order_by_cell.group_by(&:row).each do |_row, errors_for_row| %>
<%= render BulkUploadErrorRowComponent.new(bulk_upload_errors: all_answers_to_be_cleared(errors_for_row)) %> <% if all_answers_to_be_cleared(errors_for_row).present? %>
<%= render BulkUploadErrorRowComponent.new(bulk_upload_errors: all_answers_to_be_cleared(errors_for_row)) %>
<% end %>
<% end %> <% end %>
</div> </div>
</div> </div>

1
app/views/form/guidance/_privacy_notice_buyer_2024.erb

@ -0,0 +1 @@
<p class="govuk-body">Make sure the buyer has seen or been given access to <%= govuk_link_to "the Department for Levelling Up, Housing & Communities (DLUHC) privacy notice", privacy_notice_path, target: :_blank %> before completing this log. This is a legal requirement under data protection legislation.</p>

1
app/views/form/guidance/_privacy_notice_tenant_2024.erb

@ -0,0 +1 @@
<p class="govuk-body">Make sure the lead tenant has seen or been given access to <%= govuk_link_to "the Department for Levelling Up, Housing & Communities (DLUHC) privacy notice", privacy_notice_path, target: :_blank %> before completing this log. This is a legal requirement under data protection legislation.</p>

2
app/views/notifications/_notification_banner.html.erb

@ -6,7 +6,7 @@
<% if notification_count > 1 && current_user.present? %> <% if notification_count > 1 && current_user.present? %>
<p>Notification 1 of <%= notification_count %></p> <p>Notification 1 of <%= notification_count %></p>
<% end %> <% end %>
<p class="govuk-!-font-weight-bold"><%= notification.title %></p> <p class="govuk-!-font-weight-bold"><%= notification.title.html_safe %></p>
<% if notification.page_content.present? %> <% if notification.page_content.present? %>
<div class="govuk-body"> <div class="govuk-body">
<%= govuk_link_to notification.link_text, notifications_path, class: "govuk-link--inverse govuk-!-font-weight-bold" %> <%= govuk_link_to notification.link_text, notifications_path, class: "govuk-link--inverse govuk-!-font-weight-bold" %>

2
config/locales/en.yml

@ -623,6 +623,8 @@ en:
over_discounted_london_max: "The percentage discount multiplied by the purchase price is %{discount_value}. This figure should not be more than £136,400 for properties in London." over_discounted_london_max: "The percentage discount multiplied by the purchase price is %{discount_value}. This figure should not be more than £136,400 for properties in London."
over_discounted_max: "The percentage discount multiplied by the purchase price is %{discount_value}. This figure should not be more than £102,400 for properties outside of London." over_discounted_max: "The percentage discount multiplied by the purchase price is %{discount_value}. This figure should not be more than £102,400 for properties outside of London."
non_staircasing_mortgage: "The mortgage and deposit added together is %{mortgage_and_deposit_total} and the purchase price times by the equity is %{expected_shared_ownership_deposit_value}. These figures should be the same." non_staircasing_mortgage: "The mortgage and deposit added together is %{mortgage_and_deposit_total} and the purchase price times by the equity is %{expected_shared_ownership_deposit_value}. These figures should be the same."
stairowned:
mortgageused_dont_know: "The percentage owned has to be 100% if the mortgage used is 'Don’t know'"
merge_request: merge_request:
organisation_part_of_another_merge: "This organisation is part of another merge - select a different one" organisation_part_of_another_merge: "This organisation is part of another merge - select a different one"
organisation_not_selected: "Select an organisation from the search list" organisation_not_selected: "Select an organisation from the search list"

5
db/migrate/20240129161037_add_accessible_register_to_lettings_logs.rb

@ -0,0 +1,5 @@
class AddAccessibleRegisterToLettingsLogs < ActiveRecord::Migration[7.0]
def change
add_column :lettings_logs, :accessible_register, :integer
end
end

1
db/schema.rb

@ -305,6 +305,7 @@ ActiveRecord::Schema[7.0].define(version: 2024_01_30_084707) do
t.integer "duplicate_set_id" t.integer "duplicate_set_id"
t.integer "nationality_all" t.integer "nationality_all"
t.integer "nationality_all_group" t.integer "nationality_all_group"
t.integer "accessible_register"
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"
t.index ["created_by_id"], name: "index_lettings_logs_on_created_by_id" t.index ["created_by_id"], name: "index_lettings_logs_on_created_by_id"
t.index ["location_id"], name: "index_lettings_logs_on_location_id" t.index ["location_id"], name: "index_lettings_logs_on_location_id"

12
lib/tasks/clear_invalidated_earnings.rake

@ -0,0 +1,12 @@
desc "Clear earnings for lettings logs that fail validation"
task clear_invalidated_earnings: :environment do
LettingsLog.filter_by_year(2023).find_each do |lettings_log|
lettings_log.validate_net_income(lettings_log)
if lettings_log.errors[:earnings].present?
Rails.logger.info "Clearing earnings for lettings log #{lettings_log.id}, owning_organisation_id: #{lettings_log.owning_organisation_id}, managing_organisation_id: #{lettings_log.managing_organisation_id}, startdate: #{lettings_log.startdate.to_date}, tenancy reference: #{lettings_log.tenancycode}, property reference: #{lettings_log.propcode}, created_by: #{lettings_log.created_by.email}(#{lettings_log.created_by_id})"
lettings_log.earnings = nil
lettings_log.incfreq = nil
lettings_log.save!(validate: false)
end
end
end

BIN
public/files/2024_25_sales_paper_form.pdf

Binary file not shown.

1
spec/factories/lettings_log.rb

@ -112,6 +112,7 @@ FactoryBot.define do
cbl { 0 } cbl { 0 }
chr { 1 } chr { 1 }
cap { 0 } cap { 0 }
accessible_register { 0 }
reasonother { nil } reasonother { nil }
housingneeds { 1 } housingneeds { 1 }
housingneeds_type { 0 } housingneeds_type { 0 }

4
spec/fixtures/files/lettings_log_csv_export_codes.csv → spec/fixtures/files/lettings_log_csv_export_codes_23.csv vendored

@ -1,2 +1,2 @@
id,status,duplicate_set_id,created_by,is_dpo,created_at,updated_by,updated_at,creation_method,old_id,old_form_id,collection_start_year,owning_organisation_name,managing_organisation_name,needstype,lettype,renewal,startdate,renttype,renttype_detail,irproduct,irproduct_other,lar,tenancycode,propcode,postcode_known,uprn_known,uprn,uprn_confirmed,address_line1,address_line2,town_or_city,county,postcode_full,is_la_inferred,la_label,la,first_time_property_let_as_social_housing,unitletas,rsnvac,newprop,offered,unittype_gn,builtype,wchair,beds,voiddate,vacdays,void_date_value_check,majorrepairs,mrcdate,major_repairs_date_value_check,joint,startertenancy,tenancy,tenancyother,tenancylength,sheltered,declaration,hhmemb,pregnancy_value_check,refused,hhtype,totchild,totelder,totadult,age1,retirement_value_check,sex1,ethnic_group,ethnic,national,nationality_all,ecstat1,details_known_2,relat2,age2,sex2,ecstat2,details_known_3,relat3,age3,sex3,ecstat3,details_known_4,relat4,age4,sex4,ecstat4,details_known_5,relat5,age5,sex5,ecstat5,details_known_6,relat6,age6,sex6,ecstat6,details_known_7,relat7,age7,sex7,ecstat7,details_known_8,relat8,age8,sex8,ecstat8,armedforces,leftreg,reservist,preg_occ,housingneeds,housingneeds_type,housingneeds_a,housingneeds_b,housingneeds_c,housingneeds_f,housingneeds_g,housingneeds_h,housingneeds_other,illness,illness_type_4,illness_type_5,illness_type_2,illness_type_6,illness_type_7,illness_type_3,illness_type_9,illness_type_8,illness_type_1,illness_type_10,layear,waityear,reason,reasonother,prevten,new_old,homeless,ppcodenk,ppostcode_full,previous_la_known,is_previous_la_inferred,prevloc_label,prevloc,reasonpref,rp_homeless,rp_insan_unsat,rp_medwel,rp_hardship,rp_dontknow,cbl,cap,chr,letting_allocation_none,referral,referral_value_check,net_income_known,incref,earnings,incfreq,net_income_value_check,hb,has_benefits,benefits,household_charge,nocharge,period,is_carehome,chcharge,wchchrg,carehome_charges_value_check,brent,wrent,rent_value_check,scharge,wscharge,pscharge,wpschrge,supcharg,wsupchrg,tcharge,wtcharge,scharge_value_check,pscharge_value_check,supcharg_value_check,hbrentshortfall,tshortfall_known,tshortfall,wtshortfall,scheme_code,scheme_service_name,scheme_sensitive,SCHTYPE,scheme_registered_under_care_act,scheme_owning_organisation_name,scheme_primary_client_group,scheme_has_other_client_group,scheme_secondary_client_group,scheme_support_type,scheme_intended_stay,scheme_created_at,location_code,location_postcode,location_name,location_units,location_type_of_unit,location_mobility_type,location_local_authority,location_startdate id,status,duplicate_set_id,created_by,is_dpo,created_at,updated_by,updated_at,creation_method,old_id,old_form_id,collection_start_year,owning_organisation_name,managing_organisation_name,needstype,lettype,renewal,startdate,renttype,renttype_detail,irproduct,irproduct_other,lar,tenancycode,propcode,postcode_known,uprn_known,uprn,uprn_confirmed,address_line1,address_line2,town_or_city,county,postcode_full,is_la_inferred,la_label,la,first_time_property_let_as_social_housing,unitletas,rsnvac,newprop,offered,unittype_gn,builtype,wchair,beds,voiddate,vacdays,void_date_value_check,majorrepairs,mrcdate,major_repairs_date_value_check,joint,startertenancy,tenancy,tenancyother,tenancylength,sheltered,declaration,hhmemb,pregnancy_value_check,refused,hhtype,totchild,totelder,totadult,age1,retirement_value_check,sex1,ethnic_group,ethnic,nationality_all,national,ecstat1,details_known_2,relat2,age2,sex2,ecstat2,details_known_3,relat3,age3,sex3,ecstat3,details_known_4,relat4,age4,sex4,ecstat4,details_known_5,relat5,age5,sex5,ecstat5,details_known_6,relat6,age6,sex6,ecstat6,details_known_7,relat7,age7,sex7,ecstat7,details_known_8,relat8,age8,sex8,ecstat8,armedforces,leftreg,reservist,preg_occ,housingneeds,housingneeds_type,housingneeds_a,housingneeds_b,housingneeds_c,housingneeds_f,housingneeds_g,housingneeds_h,housingneeds_other,illness,illness_type_4,illness_type_5,illness_type_2,illness_type_6,illness_type_7,illness_type_3,illness_type_9,illness_type_8,illness_type_1,illness_type_10,layear,waityear,reason,reasonother,prevten,new_old,homeless,ppcodenk,ppostcode_full,previous_la_known,is_previous_la_inferred,prevloc_label,prevloc,reasonpref,rp_homeless,rp_insan_unsat,rp_medwel,rp_hardship,rp_dontknow,cbl,cap,chr,letting_allocation_none,referral,referral_value_check,net_income_known,incref,earnings,incfreq,net_income_value_check,hb,has_benefits,benefits,household_charge,nocharge,period,is_carehome,chcharge,wchchrg,carehome_charges_value_check,brent,wrent,rent_value_check,scharge,wscharge,pscharge,wpschrge,supcharg,wsupchrg,tcharge,wtcharge,scharge_value_check,pscharge_value_check,supcharg_value_check,hbrentshortfall,tshortfall_known,tshortfall,wtshortfall,scheme_code,scheme_service_name,scheme_sensitive,SCHTYPE,scheme_registered_under_care_act,scheme_owning_organisation_name,scheme_primary_client_group,scheme_has_other_client_group,scheme_secondary_client_group,scheme_support_type,scheme_intended_stay,scheme_created_at,location_code,location_postcode,location_name,location_units,location_type_of_unit,location_mobility_type,location_local_authority,location_startdate
,completed,,s.port@jeemayle.com,false,2023-11-26T00:00:00+00:00,,2023-11-26T00:00:00+00:00,1,,,2023,DLUHC,DLUHC,1,7,0,2023-11-26,2,2,1,,2,HIJKLMN,ABCDEFG,1,0,,,fake address,,London,,NW9 5LL,false,Barnet,E09000003,0,2,6,2,2,7,1,1,3,2023-11-24,,,1,2023-11-25,,3,1,4,,2,,1,4,,1,4,0,0,2,35,,F,0,2,13,,0,0,P,32,M,6,1,R,-9,R,10,0,R,-9,R,10,,,,,,,,,,,,,,,,,,,,,1,4,1,2,1,0,1,0,0,0,0,0,0,1,0,0,1,0,0,0,0,0,0,0,2,7,4,,6,2,1,0,TN23 6LZ,1,false,Ashford,E07000105,1,0,1,0,0,0,0,0,1,,2,,0,0,268,1,,6,1,1,,0,2,,,,,200.0,100.0,,50.0,25.0,40.0,20.0,35.0,17.5,325.0,162.5,,,,1,0,12.0,6.0,,,,,,,,,,,,,,,,,,,, ,completed,,s.port@jeemayle.com,false,2023-11-26T00:00:00+00:00,,2023-11-26T00:00:00+00:00,1,,,2023,DLUHC,DLUHC,1,7,0,2023-11-26,2,2,1,,2,HIJKLMN,ABCDEFG,1,0,,,fake address,,London,,NW9 5LL,false,Barnet,E09000003,0,2,6,2,2,7,1,1,3,2023-11-24,,,1,2023-11-25,,3,1,4,,2,,1,4,,1,4,0,0,2,35,,F,0,2,,13,0,0,P,32,M,6,1,R,-9,R,10,0,R,-9,R,10,,,,,,,,,,,,,,,,,,,,,1,4,1,2,1,0,1,0,0,0,0,0,0,1,0,0,1,0,0,0,0,0,0,0,2,7,4,,6,2,1,0,TN23 6LZ,1,false,Ashford,E07000105,1,0,1,0,0,0,0,0,1,,2,,0,0,268,1,,6,1,1,,0,2,,,,,200.0,100.0,,50.0,25.0,40.0,20.0,35.0,17.5,325.0,162.5,,,,1,0,12.0,6.0,,,,,,,,,,,,,,,,,,,,
1 id status duplicate_set_id created_by is_dpo created_at updated_by updated_at creation_method old_id old_form_id collection_start_year owning_organisation_name managing_organisation_name needstype lettype renewal startdate renttype renttype_detail irproduct irproduct_other lar tenancycode propcode postcode_known uprn_known uprn uprn_confirmed address_line1 address_line2 town_or_city county postcode_full is_la_inferred la_label la first_time_property_let_as_social_housing unitletas rsnvac newprop offered unittype_gn builtype wchair beds voiddate vacdays void_date_value_check majorrepairs mrcdate major_repairs_date_value_check joint startertenancy tenancy tenancyother tenancylength sheltered declaration hhmemb pregnancy_value_check refused hhtype totchild totelder totadult age1 retirement_value_check sex1 ethnic_group ethnic nationality_all national ecstat1 details_known_2 relat2 age2 sex2 ecstat2 details_known_3 relat3 age3 sex3 ecstat3 details_known_4 relat4 age4 sex4 ecstat4 details_known_5 relat5 age5 sex5 ecstat5 details_known_6 relat6 age6 sex6 ecstat6 details_known_7 relat7 age7 sex7 ecstat7 details_known_8 relat8 age8 sex8 ecstat8 armedforces leftreg reservist preg_occ housingneeds housingneeds_type housingneeds_a housingneeds_b housingneeds_c housingneeds_f housingneeds_g housingneeds_h housingneeds_other illness illness_type_4 illness_type_5 illness_type_2 illness_type_6 illness_type_7 illness_type_3 illness_type_9 illness_type_8 illness_type_1 illness_type_10 layear waityear reason reasonother prevten new_old homeless ppcodenk ppostcode_full previous_la_known is_previous_la_inferred prevloc_label prevloc reasonpref rp_homeless rp_insan_unsat rp_medwel rp_hardship rp_dontknow cbl cap chr letting_allocation_none referral referral_value_check net_income_known incref earnings incfreq net_income_value_check hb has_benefits benefits household_charge nocharge period is_carehome chcharge wchchrg carehome_charges_value_check brent wrent rent_value_check scharge wscharge pscharge wpschrge supcharg wsupchrg tcharge wtcharge scharge_value_check pscharge_value_check supcharg_value_check hbrentshortfall tshortfall_known tshortfall wtshortfall scheme_code scheme_service_name scheme_sensitive SCHTYPE scheme_registered_under_care_act scheme_owning_organisation_name scheme_primary_client_group scheme_has_other_client_group scheme_secondary_client_group scheme_support_type scheme_intended_stay scheme_created_at location_code location_postcode location_name location_units location_type_of_unit location_mobility_type location_local_authority location_startdate
2 completed s.port@jeemayle.com false 2023-11-26T00:00:00+00:00 2023-11-26T00:00:00+00:00 1 2023 DLUHC DLUHC 1 7 0 2023-11-26 2 2 1 2 HIJKLMN ABCDEFG 1 0 fake address London NW9 5LL false Barnet E09000003 0 2 6 2 2 7 1 1 3 2023-11-24 1 2023-11-25 3 1 4 2 1 4 1 4 0 0 2 35 F 0 2 13 0 0 P 32 M 6 1 R -9 R 10 0 R -9 R 10 1 4 1 2 1 0 1 0 0 0 0 0 0 1 0 0 1 0 0 0 0 0 0 0 2 7 4 6 2 1 0 TN23 6LZ 1 false Ashford E07000105 1 0 1 0 0 0 0 0 1 2 0 0 268 1 6 1 1 0 2 200.0 100.0 50.0 25.0 40.0 20.0 35.0 17.5 325.0 162.5 1 0 12.0 6.0

2
spec/fixtures/files/lettings_log_csv_export_codes_24.csv vendored

@ -0,0 +1,2 @@
id,status,duplicate_set_id,created_by,is_dpo,created_at,updated_by,updated_at,creation_method,old_id,old_form_id,collection_start_year,owning_organisation_name,managing_organisation_name,needstype,lettype,renewal,startdate,renttype,renttype_detail,irproduct,irproduct_other,lar,tenancycode,propcode,declaration,postcode_known,uprn_known,uprn,uprn_confirmed,address_line1,address_line2,town_or_city,county,postcode_full,is_la_inferred,la_label,la,first_time_property_let_as_social_housing,unitletas,rsnvac,newprop,offered,unittype_gn,builtype,wchair,beds,voiddate,vacdays,void_date_value_check,majorrepairs,mrcdate,major_repairs_date_value_check,joint,startertenancy,tenancy,tenancyother,tenancylength,sheltered,hhmemb,pregnancy_value_check,refused,hhtype,totchild,totelder,totadult,age1,retirement_value_check,sex1,ethnic_group,ethnic,national,nationality_all,ecstat1,details_known_2,relat2,age2,sex2,ecstat2,details_known_3,relat3,age3,sex3,ecstat3,details_known_4,relat4,age4,sex4,ecstat4,details_known_5,relat5,age5,sex5,ecstat5,details_known_6,relat6,age6,sex6,ecstat6,details_known_7,relat7,age7,sex7,ecstat7,details_known_8,relat8,age8,sex8,ecstat8,armedforces,leftreg,reservist,preg_occ,housingneeds,housingneeds_type,housingneeds_a,housingneeds_b,housingneeds_c,housingneeds_f,housingneeds_g,housingneeds_h,housingneeds_other,illness,illness_type_4,illness_type_5,illness_type_2,illness_type_6,illness_type_7,illness_type_3,illness_type_9,illness_type_8,illness_type_1,illness_type_10,layear,waityear,reason,reasonother,prevten,new_old,homeless,ppcodenk,ppostcode_full,previous_la_known,is_previous_la_inferred,prevloc_label,prevloc,reasonpref,rp_homeless,rp_insan_unsat,rp_medwel,rp_hardship,rp_dontknow,cbl,cap,chr,accessible_register,letting_allocation_none,referral,referral_value_check,net_income_known,incref,earnings,incfreq,net_income_value_check,hb,has_benefits,benefits,household_charge,nocharge,period,is_carehome,chcharge,wchchrg,carehome_charges_value_check,brent,wrent,rent_value_check,scharge,wscharge,pscharge,wpschrge,supcharg,wsupchrg,tcharge,wtcharge,scharge_value_check,pscharge_value_check,supcharg_value_check,hbrentshortfall,tshortfall_known,tshortfall,wtshortfall,scheme_code,scheme_service_name,scheme_sensitive,SCHTYPE,scheme_registered_under_care_act,scheme_owning_organisation_name,scheme_primary_client_group,scheme_has_other_client_group,scheme_secondary_client_group,scheme_support_type,scheme_intended_stay,scheme_created_at,location_code,location_postcode,location_name,location_units,location_type_of_unit,location_mobility_type,location_local_authority,location_startdate
,completed,,s.port@jeemayle.com,false,2023-11-26T00:00:00+00:00,,2024-04-01T00:00:00+01:00,1,,,2023,DLUHC,DLUHC,1,7,0,2023-11-26,2,2,1,,2,HIJKLMN,ABCDEFG,1,1,0,,,fake address,,London,,NW9 5LL,false,Barnet,E09000003,0,2,6,2,2,7,1,1,3,2023-11-24,,,1,2023-11-25,,3,1,4,,2,,4,,1,4,0,0,2,35,,F,0,2,13,,0,0,P,32,M,6,1,R,-9,R,10,0,R,-9,R,10,,,,,,,,,,,,,,,,,,,,,1,4,1,2,1,0,1,0,0,0,0,0,0,1,0,0,1,0,0,0,0,0,0,0,2,7,4,,6,2,1,0,TN23 6LZ,1,false,Ashford,E07000105,1,0,1,0,0,0,0,0,1,0,,2,,0,0,268,1,,6,1,1,,0,2,,,,,200.0,100.0,,50.0,25.0,40.0,20.0,35.0,17.5,325.0,162.5,,,,1,0,12.0,6.0,,,,,,,,,,,,,,,,,,,,
1 id status duplicate_set_id created_by is_dpo created_at updated_by updated_at creation_method old_id old_form_id collection_start_year owning_organisation_name managing_organisation_name needstype lettype renewal startdate renttype renttype_detail irproduct irproduct_other lar tenancycode propcode declaration postcode_known uprn_known uprn uprn_confirmed address_line1 address_line2 town_or_city county postcode_full is_la_inferred la_label la first_time_property_let_as_social_housing unitletas rsnvac newprop offered unittype_gn builtype wchair beds voiddate vacdays void_date_value_check majorrepairs mrcdate major_repairs_date_value_check joint startertenancy tenancy tenancyother tenancylength sheltered hhmemb pregnancy_value_check refused hhtype totchild totelder totadult age1 retirement_value_check sex1 ethnic_group ethnic national nationality_all ecstat1 details_known_2 relat2 age2 sex2 ecstat2 details_known_3 relat3 age3 sex3 ecstat3 details_known_4 relat4 age4 sex4 ecstat4 details_known_5 relat5 age5 sex5 ecstat5 details_known_6 relat6 age6 sex6 ecstat6 details_known_7 relat7 age7 sex7 ecstat7 details_known_8 relat8 age8 sex8 ecstat8 armedforces leftreg reservist preg_occ housingneeds housingneeds_type housingneeds_a housingneeds_b housingneeds_c housingneeds_f housingneeds_g housingneeds_h housingneeds_other illness illness_type_4 illness_type_5 illness_type_2 illness_type_6 illness_type_7 illness_type_3 illness_type_9 illness_type_8 illness_type_1 illness_type_10 layear waityear reason reasonother prevten new_old homeless ppcodenk ppostcode_full previous_la_known is_previous_la_inferred prevloc_label prevloc reasonpref rp_homeless rp_insan_unsat rp_medwel rp_hardship rp_dontknow cbl cap chr accessible_register letting_allocation_none referral referral_value_check net_income_known incref earnings incfreq net_income_value_check hb has_benefits benefits household_charge nocharge period is_carehome chcharge wchchrg carehome_charges_value_check brent wrent rent_value_check scharge wscharge pscharge wpschrge supcharg wsupchrg tcharge wtcharge scharge_value_check pscharge_value_check supcharg_value_check hbrentshortfall tshortfall_known tshortfall wtshortfall scheme_code scheme_service_name scheme_sensitive SCHTYPE scheme_registered_under_care_act scheme_owning_organisation_name scheme_primary_client_group scheme_has_other_client_group scheme_secondary_client_group scheme_support_type scheme_intended_stay scheme_created_at location_code location_postcode location_name location_units location_type_of_unit location_mobility_type location_local_authority location_startdate
2 completed s.port@jeemayle.com false 2023-11-26T00:00:00+00:00 2024-04-01T00:00:00+01:00 1 2023 DLUHC DLUHC 1 7 0 2023-11-26 2 2 1 2 HIJKLMN ABCDEFG 1 1 0 fake address London NW9 5LL false Barnet E09000003 0 2 6 2 2 7 1 1 3 2023-11-24 1 2023-11-25 3 1 4 2 4 1 4 0 0 2 35 F 0 2 13 0 0 P 32 M 6 1 R -9 R 10 0 R -9 R 10 1 4 1 2 1 0 1 0 0 0 0 0 0 1 0 0 1 0 0 0 0 0 0 0 2 7 4 6 2 1 0 TN23 6LZ 1 false Ashford E07000105 1 0 1 0 0 0 0 0 1 0 2 0 0 268 1 6 1 1 0 2 200.0 100.0 50.0 25.0 40.0 20.0 35.0 17.5 325.0 162.5 1 0 12.0 6.0

4
spec/fixtures/files/lettings_log_csv_export_labels.csv → spec/fixtures/files/lettings_log_csv_export_labels_23.csv vendored

@ -1,2 +1,2 @@
id,status,duplicate_set_id,created_by,is_dpo,created_at,updated_by,updated_at,creation_method,old_id,old_form_id,collection_start_year,owning_organisation_name,managing_organisation_name,needstype,lettype,renewal,startdate,renttype,renttype_detail,irproduct,irproduct_other,lar,tenancycode,propcode,postcode_known,uprn_known,uprn,uprn_confirmed,address_line1,address_line2,town_or_city,county,postcode_full,is_la_inferred,la_label,la,first_time_property_let_as_social_housing,unitletas,rsnvac,newprop,offered,unittype_gn,builtype,wchair,beds,voiddate,vacdays,void_date_value_check,majorrepairs,mrcdate,major_repairs_date_value_check,joint,startertenancy,tenancy,tenancyother,tenancylength,sheltered,declaration,hhmemb,pregnancy_value_check,refused,hhtype,totchild,totelder,totadult,age1,retirement_value_check,sex1,ethnic_group,ethnic,national,nationality_all,ecstat1,details_known_2,relat2,age2,sex2,ecstat2,details_known_3,relat3,age3,sex3,ecstat3,details_known_4,relat4,age4,sex4,ecstat4,details_known_5,relat5,age5,sex5,ecstat5,details_known_6,relat6,age6,sex6,ecstat6,details_known_7,relat7,age7,sex7,ecstat7,details_known_8,relat8,age8,sex8,ecstat8,armedforces,leftreg,reservist,preg_occ,housingneeds,housingneeds_type,housingneeds_a,housingneeds_b,housingneeds_c,housingneeds_f,housingneeds_g,housingneeds_h,housingneeds_other,illness,illness_type_4,illness_type_5,illness_type_2,illness_type_6,illness_type_7,illness_type_3,illness_type_9,illness_type_8,illness_type_1,illness_type_10,layear,waityear,reason,reasonother,prevten,new_old,homeless,ppcodenk,ppostcode_full,previous_la_known,is_previous_la_inferred,prevloc_label,prevloc,reasonpref,rp_homeless,rp_insan_unsat,rp_medwel,rp_hardship,rp_dontknow,cbl,cap,chr,letting_allocation_none,referral,referral_value_check,net_income_known,incref,earnings,incfreq,net_income_value_check,hb,has_benefits,benefits,household_charge,nocharge,period,is_carehome,chcharge,wchchrg,carehome_charges_value_check,brent,wrent,rent_value_check,scharge,wscharge,pscharge,wpschrge,supcharg,wsupchrg,tcharge,wtcharge,scharge_value_check,pscharge_value_check,supcharg_value_check,hbrentshortfall,tshortfall_known,tshortfall,wtshortfall,scheme_code,scheme_service_name,scheme_sensitive,SCHTYPE,scheme_registered_under_care_act,scheme_owning_organisation_name,scheme_primary_client_group,scheme_has_other_client_group,scheme_secondary_client_group,scheme_support_type,scheme_intended_stay,scheme_created_at,location_code,location_postcode,location_name,location_units,location_type_of_unit,location_mobility_type,location_local_authority,location_startdate id,status,duplicate_set_id,created_by,is_dpo,created_at,updated_by,updated_at,creation_method,old_id,old_form_id,collection_start_year,owning_organisation_name,managing_organisation_name,needstype,lettype,renewal,startdate,renttype,renttype_detail,irproduct,irproduct_other,lar,tenancycode,propcode,postcode_known,uprn_known,uprn,uprn_confirmed,address_line1,address_line2,town_or_city,county,postcode_full,is_la_inferred,la_label,la,first_time_property_let_as_social_housing,unitletas,rsnvac,newprop,offered,unittype_gn,builtype,wchair,beds,voiddate,vacdays,void_date_value_check,majorrepairs,mrcdate,major_repairs_date_value_check,joint,startertenancy,tenancy,tenancyother,tenancylength,sheltered,declaration,hhmemb,pregnancy_value_check,refused,hhtype,totchild,totelder,totadult,age1,retirement_value_check,sex1,ethnic_group,ethnic,nationality_all,national,ecstat1,details_known_2,relat2,age2,sex2,ecstat2,details_known_3,relat3,age3,sex3,ecstat3,details_known_4,relat4,age4,sex4,ecstat4,details_known_5,relat5,age5,sex5,ecstat5,details_known_6,relat6,age6,sex6,ecstat6,details_known_7,relat7,age7,sex7,ecstat7,details_known_8,relat8,age8,sex8,ecstat8,armedforces,leftreg,reservist,preg_occ,housingneeds,housingneeds_type,housingneeds_a,housingneeds_b,housingneeds_c,housingneeds_f,housingneeds_g,housingneeds_h,housingneeds_other,illness,illness_type_4,illness_type_5,illness_type_2,illness_type_6,illness_type_7,illness_type_3,illness_type_9,illness_type_8,illness_type_1,illness_type_10,layear,waityear,reason,reasonother,prevten,new_old,homeless,ppcodenk,ppostcode_full,previous_la_known,is_previous_la_inferred,prevloc_label,prevloc,reasonpref,rp_homeless,rp_insan_unsat,rp_medwel,rp_hardship,rp_dontknow,cbl,cap,chr,letting_allocation_none,referral,referral_value_check,net_income_known,incref,earnings,incfreq,net_income_value_check,hb,has_benefits,benefits,household_charge,nocharge,period,is_carehome,chcharge,wchchrg,carehome_charges_value_check,brent,wrent,rent_value_check,scharge,wscharge,pscharge,wpschrge,supcharg,wsupchrg,tcharge,wtcharge,scharge_value_check,pscharge_value_check,supcharg_value_check,hbrentshortfall,tshortfall_known,tshortfall,wtshortfall,scheme_code,scheme_service_name,scheme_sensitive,SCHTYPE,scheme_registered_under_care_act,scheme_owning_organisation_name,scheme_primary_client_group,scheme_has_other_client_group,scheme_secondary_client_group,scheme_support_type,scheme_intended_stay,scheme_created_at,location_code,location_postcode,location_name,location_units,location_type_of_unit,location_mobility_type,location_local_authority,location_startdate
,completed,,s.port@jeemayle.com,false,2023-11-26T00:00:00+00:00,,2023-11-26T00:00:00+00:00,single log,,,2023,DLUHC,DLUHC,General needs,Affordable rent general needs local authority,No,2023-11-26,Affordable Rent,Affordable Rent,Rent to Buy,,No,HIJKLMN,ABCDEFG,Yes,No,,,fake address,,London,,NW9 5LL,No,Barnet,E09000003,No,Affordable rent basis,Tenant abandoned property,No,2,House,Purpose built,Yes,3,2023-11-24,,,Yes,2023-11-25,,Don’t know,Yes,Assured Shorthold Tenancy (AST) – Fixed term,,2,,Yes,4,,Yes,4,0,0,2,35,,Female,White,Irish,Tenant prefers not to say,,Other,Yes,Partner,32,Male,Not seeking work,No,Prefers not to say,Not known,Prefers not to say,Prefers not to say,Yes,Person prefers not to say,Not known,Person prefers not to say,Person prefers not to say,,,,,,,,,,,,,,,,,,,,,Yes – the person is a current or former regular,No – they left up to and including 5 years ago,Yes,No,Yes,Fully wheelchair accessible housing,Yes,No,No,No,No,No,No,Yes,No,No,Yes,No,No,No,No,No,No,No,Less than 1 year,1 year but under 2 years,Loss of tied accommodation,,Other supported housing,2,No,Yes,TN23 6LZ,Yes,No,Ashford,E07000105,Yes,,Yes,,,,No,No,Yes,,Tenant applied directly (no referral or nomination),,Yes,No,268,Weekly,,Universal Credit housing element,Yes,All,,No,Every 2 weeks,,,,,200.0,100.0,,50.0,25.0,40.0,20.0,35.0,17.5,325.0,162.5,,,,Yes,Yes,12.0,6.0,,,,,,,,,,,,,,,,,,,, ,completed,,s.port@jeemayle.com,false,2023-11-26T00:00:00+00:00,,2023-11-26T00:00:00+00:00,single log,,,2023,DLUHC,DLUHC,General needs,Affordable rent general needs local authority,No,2023-11-26,Affordable Rent,Affordable Rent,Rent to Buy,,No,HIJKLMN,ABCDEFG,Yes,No,,,fake address,,London,,NW9 5LL,No,Barnet,E09000003,No,Affordable rent basis,Tenant abandoned property,No,2,House,Purpose built,Yes,3,2023-11-24,,,Yes,2023-11-25,,Don’t know,Yes,Assured Shorthold Tenancy (AST) – Fixed term,,2,,Yes,4,,Yes,4,0,0,2,35,,Female,White,Irish,,Tenant prefers not to say,Other,Yes,Partner,32,Male,Not seeking work,No,Prefers not to say,Not known,Prefers not to say,Prefers not to say,Yes,Person prefers not to say,Not known,Person prefers not to say,Person prefers not to say,,,,,,,,,,,,,,,,,,,,,Yes – the person is a current or former regular,No – they left up to and including 5 years ago,Yes,No,Yes,Fully wheelchair accessible housing,Yes,No,No,No,No,No,No,Yes,No,No,Yes,No,No,No,No,No,No,No,Less than 1 year,1 year but under 2 years,Loss of tied accommodation,,Other supported housing,2,No,Yes,TN23 6LZ,Yes,No,Ashford,E07000105,Yes,,Yes,,,,No,No,Yes,,Tenant applied directly (no referral or nomination),,Yes,No,268,Weekly,,Universal Credit housing element,Yes,All,,No,Every 2 weeks,,,,,200.0,100.0,,50.0,25.0,40.0,20.0,35.0,17.5,325.0,162.5,,,,Yes,Yes,12.0,6.0,,,,,,,,,,,,,,,,,,,,
1 id status duplicate_set_id created_by is_dpo created_at updated_by updated_at creation_method old_id old_form_id collection_start_year owning_organisation_name managing_organisation_name needstype lettype renewal startdate renttype renttype_detail irproduct irproduct_other lar tenancycode propcode postcode_known uprn_known uprn uprn_confirmed address_line1 address_line2 town_or_city county postcode_full is_la_inferred la_label la first_time_property_let_as_social_housing unitletas rsnvac newprop offered unittype_gn builtype wchair beds voiddate vacdays void_date_value_check majorrepairs mrcdate major_repairs_date_value_check joint startertenancy tenancy tenancyother tenancylength sheltered declaration hhmemb pregnancy_value_check refused hhtype totchild totelder totadult age1 retirement_value_check sex1 ethnic_group ethnic nationality_all national ecstat1 details_known_2 relat2 age2 sex2 ecstat2 details_known_3 relat3 age3 sex3 ecstat3 details_known_4 relat4 age4 sex4 ecstat4 details_known_5 relat5 age5 sex5 ecstat5 details_known_6 relat6 age6 sex6 ecstat6 details_known_7 relat7 age7 sex7 ecstat7 details_known_8 relat8 age8 sex8 ecstat8 armedforces leftreg reservist preg_occ housingneeds housingneeds_type housingneeds_a housingneeds_b housingneeds_c housingneeds_f housingneeds_g housingneeds_h housingneeds_other illness illness_type_4 illness_type_5 illness_type_2 illness_type_6 illness_type_7 illness_type_3 illness_type_9 illness_type_8 illness_type_1 illness_type_10 layear waityear reason reasonother prevten new_old homeless ppcodenk ppostcode_full previous_la_known is_previous_la_inferred prevloc_label prevloc reasonpref rp_homeless rp_insan_unsat rp_medwel rp_hardship rp_dontknow cbl cap chr letting_allocation_none referral referral_value_check net_income_known incref earnings incfreq net_income_value_check hb has_benefits benefits household_charge nocharge period is_carehome chcharge wchchrg carehome_charges_value_check brent wrent rent_value_check scharge wscharge pscharge wpschrge supcharg wsupchrg tcharge wtcharge scharge_value_check pscharge_value_check supcharg_value_check hbrentshortfall tshortfall_known tshortfall wtshortfall scheme_code scheme_service_name scheme_sensitive SCHTYPE scheme_registered_under_care_act scheme_owning_organisation_name scheme_primary_client_group scheme_has_other_client_group scheme_secondary_client_group scheme_support_type scheme_intended_stay scheme_created_at location_code location_postcode location_name location_units location_type_of_unit location_mobility_type location_local_authority location_startdate
2 completed s.port@jeemayle.com false 2023-11-26T00:00:00+00:00 2023-11-26T00:00:00+00:00 single log 2023 DLUHC DLUHC General needs Affordable rent general needs local authority No 2023-11-26 Affordable Rent Affordable Rent Rent to Buy No HIJKLMN ABCDEFG Yes No fake address London NW9 5LL No Barnet E09000003 No Affordable rent basis Tenant abandoned property No 2 House Purpose built Yes 3 2023-11-24 Yes 2023-11-25 Don’t know Yes Assured Shorthold Tenancy (AST) – Fixed term 2 Yes 4 Yes 4 0 0 2 35 Female White Irish Tenant prefers not to say Other Yes Partner 32 Male Not seeking work No Prefers not to say Not known Prefers not to say Prefers not to say Yes Person prefers not to say Not known Person prefers not to say Person prefers not to say Yes – the person is a current or former regular No – they left up to and including 5 years ago Yes No Yes Fully wheelchair accessible housing Yes No No No No No No Yes No No Yes No No No No No No No Less than 1 year 1 year but under 2 years Loss of tied accommodation Other supported housing 2 No Yes TN23 6LZ Yes No Ashford E07000105 Yes Yes No No Yes Tenant applied directly (no referral or nomination) Yes No 268 Weekly Universal Credit housing element Yes All No Every 2 weeks 200.0 100.0 50.0 25.0 40.0 20.0 35.0 17.5 325.0 162.5 Yes Yes 12.0 6.0

2
spec/fixtures/files/lettings_log_csv_export_labels_24.csv vendored

@ -0,0 +1,2 @@
id,status,duplicate_set_id,created_by,is_dpo,created_at,updated_by,updated_at,creation_method,old_id,old_form_id,collection_start_year,owning_organisation_name,managing_organisation_name,needstype,lettype,renewal,startdate,renttype,renttype_detail,irproduct,irproduct_other,lar,tenancycode,propcode,declaration,postcode_known,uprn_known,uprn,uprn_confirmed,address_line1,address_line2,town_or_city,county,postcode_full,is_la_inferred,la_label,la,first_time_property_let_as_social_housing,unitletas,rsnvac,newprop,offered,unittype_gn,builtype,wchair,beds,voiddate,vacdays,void_date_value_check,majorrepairs,mrcdate,major_repairs_date_value_check,joint,startertenancy,tenancy,tenancyother,tenancylength,sheltered,hhmemb,pregnancy_value_check,refused,hhtype,totchild,totelder,totadult,age1,retirement_value_check,sex1,ethnic_group,ethnic,national,nationality_all,ecstat1,details_known_2,relat2,age2,sex2,ecstat2,details_known_3,relat3,age3,sex3,ecstat3,details_known_4,relat4,age4,sex4,ecstat4,details_known_5,relat5,age5,sex5,ecstat5,details_known_6,relat6,age6,sex6,ecstat6,details_known_7,relat7,age7,sex7,ecstat7,details_known_8,relat8,age8,sex8,ecstat8,armedforces,leftreg,reservist,preg_occ,housingneeds,housingneeds_type,housingneeds_a,housingneeds_b,housingneeds_c,housingneeds_f,housingneeds_g,housingneeds_h,housingneeds_other,illness,illness_type_4,illness_type_5,illness_type_2,illness_type_6,illness_type_7,illness_type_3,illness_type_9,illness_type_8,illness_type_1,illness_type_10,layear,waityear,reason,reasonother,prevten,new_old,homeless,ppcodenk,ppostcode_full,previous_la_known,is_previous_la_inferred,prevloc_label,prevloc,reasonpref,rp_homeless,rp_insan_unsat,rp_medwel,rp_hardship,rp_dontknow,cbl,cap,chr,accessible_register,letting_allocation_none,referral,referral_value_check,net_income_known,incref,earnings,incfreq,net_income_value_check,hb,has_benefits,benefits,household_charge,nocharge,period,is_carehome,chcharge,wchchrg,carehome_charges_value_check,brent,wrent,rent_value_check,scharge,wscharge,pscharge,wpschrge,supcharg,wsupchrg,tcharge,wtcharge,scharge_value_check,pscharge_value_check,supcharg_value_check,hbrentshortfall,tshortfall_known,tshortfall,wtshortfall,scheme_code,scheme_service_name,scheme_sensitive,SCHTYPE,scheme_registered_under_care_act,scheme_owning_organisation_name,scheme_primary_client_group,scheme_has_other_client_group,scheme_secondary_client_group,scheme_support_type,scheme_intended_stay,scheme_created_at,location_code,location_postcode,location_name,location_units,location_type_of_unit,location_mobility_type,location_local_authority,location_startdate
,completed,,s.port@jeemayle.com,false,2023-11-26T00:00:00+00:00,,2024-04-01T00:00:00+01:00,single log,,,2023,DLUHC,DLUHC,General needs,Affordable rent general needs local authority,No,2023-11-26,Affordable Rent,Affordable Rent,Rent to Buy,,No,HIJKLMN,ABCDEFG,Yes,Yes,No,,,fake address,,London,,NW9 5LL,No,Barnet,E09000003,No,Affordable rent basis,Tenant abandoned property,No,2,House,Purpose built,Yes,3,2023-11-24,,,Yes,2023-11-25,,Don’t know,Yes,Assured Shorthold Tenancy (AST) – Fixed term,,2,,4,,Yes,4,0,0,2,35,,Female,White,Irish,Tenant prefers not to say,,Other,Yes,Partner,32,Male,Not seeking work,No,Prefers not to say,Not known,Prefers not to say,Prefers not to say,Yes,Person prefers not to say,Not known,Person prefers not to say,Person prefers not to say,,,,,,,,,,,,,,,,,,,,,Yes – the person is a current or former regular,No – they left up to and including 5 years ago,Yes,No,Yes,Fully wheelchair accessible housing,Yes,No,No,No,No,No,No,Yes,No,No,Yes,No,No,No,No,No,No,No,Less than 1 year,1 year but under 2 years,Loss of tied accommodation,,Other supported housing,2,No,Yes,TN23 6LZ,Yes,No,Ashford,E07000105,Yes,,Yes,,,,No,No,Yes,No,,Tenant applied directly (no referral or nomination),,Yes,No,268,Weekly,,Universal Credit housing element,Yes,All,,No,Every 2 weeks,,,,,200.0,100.0,,50.0,25.0,40.0,20.0,35.0,17.5,325.0,162.5,,,,Yes,Yes,12.0,6.0,,,,,,,,,,,,,,,,,,,,
1 id status duplicate_set_id created_by is_dpo created_at updated_by updated_at creation_method old_id old_form_id collection_start_year owning_organisation_name managing_organisation_name needstype lettype renewal startdate renttype renttype_detail irproduct irproduct_other lar tenancycode propcode declaration postcode_known uprn_known uprn uprn_confirmed address_line1 address_line2 town_or_city county postcode_full is_la_inferred la_label la first_time_property_let_as_social_housing unitletas rsnvac newprop offered unittype_gn builtype wchair beds voiddate vacdays void_date_value_check majorrepairs mrcdate major_repairs_date_value_check joint startertenancy tenancy tenancyother tenancylength sheltered hhmemb pregnancy_value_check refused hhtype totchild totelder totadult age1 retirement_value_check sex1 ethnic_group ethnic national nationality_all ecstat1 details_known_2 relat2 age2 sex2 ecstat2 details_known_3 relat3 age3 sex3 ecstat3 details_known_4 relat4 age4 sex4 ecstat4 details_known_5 relat5 age5 sex5 ecstat5 details_known_6 relat6 age6 sex6 ecstat6 details_known_7 relat7 age7 sex7 ecstat7 details_known_8 relat8 age8 sex8 ecstat8 armedforces leftreg reservist preg_occ housingneeds housingneeds_type housingneeds_a housingneeds_b housingneeds_c housingneeds_f housingneeds_g housingneeds_h housingneeds_other illness illness_type_4 illness_type_5 illness_type_2 illness_type_6 illness_type_7 illness_type_3 illness_type_9 illness_type_8 illness_type_1 illness_type_10 layear waityear reason reasonother prevten new_old homeless ppcodenk ppostcode_full previous_la_known is_previous_la_inferred prevloc_label prevloc reasonpref rp_homeless rp_insan_unsat rp_medwel rp_hardship rp_dontknow cbl cap chr accessible_register letting_allocation_none referral referral_value_check net_income_known incref earnings incfreq net_income_value_check hb has_benefits benefits household_charge nocharge period is_carehome chcharge wchchrg carehome_charges_value_check brent wrent rent_value_check scharge wscharge pscharge wpschrge supcharg wsupchrg tcharge wtcharge scharge_value_check pscharge_value_check supcharg_value_check hbrentshortfall tshortfall_known tshortfall wtshortfall scheme_code scheme_service_name scheme_sensitive SCHTYPE scheme_registered_under_care_act scheme_owning_organisation_name scheme_primary_client_group scheme_has_other_client_group scheme_secondary_client_group scheme_support_type scheme_intended_stay scheme_created_at location_code location_postcode location_name location_units location_type_of_unit location_mobility_type location_local_authority location_startdate
2 completed s.port@jeemayle.com false 2023-11-26T00:00:00+00:00 2024-04-01T00:00:00+01:00 single log 2023 DLUHC DLUHC General needs Affordable rent general needs local authority No 2023-11-26 Affordable Rent Affordable Rent Rent to Buy No HIJKLMN ABCDEFG Yes Yes No fake address London NW9 5LL No Barnet E09000003 No Affordable rent basis Tenant abandoned property No 2 House Purpose built Yes 3 2023-11-24 Yes 2023-11-25 Don’t know Yes Assured Shorthold Tenancy (AST) – Fixed term 2 4 Yes 4 0 0 2 35 Female White Irish Tenant prefers not to say Other Yes Partner 32 Male Not seeking work No Prefers not to say Not known Prefers not to say Prefers not to say Yes Person prefers not to say Not known Person prefers not to say Person prefers not to say Yes – the person is a current or former regular No – they left up to and including 5 years ago Yes No Yes Fully wheelchair accessible housing Yes No No No No No No Yes No No Yes No No No No No No No Less than 1 year 1 year but under 2 years Loss of tied accommodation Other supported housing 2 No Yes TN23 6LZ Yes No Ashford E07000105 Yes Yes No No Yes No Tenant applied directly (no referral or nomination) Yes No 268 Weekly Universal Credit housing element Yes All No Every 2 weeks 200.0 100.0 50.0 25.0 40.0 20.0 35.0 17.5 325.0 162.5 Yes Yes 12.0 6.0

4
spec/fixtures/files/lettings_log_csv_export_non_support_codes.csv → spec/fixtures/files/lettings_log_csv_export_non_support_codes_23.csv vendored

@ -1,2 +1,2 @@
id,status,duplicate_set_id,created_by,is_dpo,created_at,updated_by,updated_at,creation_method,collection_start_year,owning_organisation_name,managing_organisation_name,needstype,lettype,renewal,startdate,renttype,renttype_detail,irproduct,irproduct_other,lar,tenancycode,propcode,uprn_known,uprn,address_line1,address_line2,town_or_city,county,postcode_full,la_label,unitletas,rsnvac,newprop,offered,unittype_gn,builtype,wchair,beds,voiddate,vacdays,void_date_value_check,majorrepairs,mrcdate,major_repairs_date_value_check,joint,startertenancy,tenancy,tenancyother,tenancylength,sheltered,declaration,hhmemb,refused,age1,sex1,ethnic_group,ethnic,national,nationality_all,ecstat1,relat2,age2,sex2,ecstat2,relat3,age3,sex3,ecstat3,relat4,age4,sex4,ecstat4,relat5,age5,sex5,ecstat5,relat6,age6,sex6,ecstat6,relat7,age7,sex7,ecstat7,relat8,age8,sex8,ecstat8,armedforces,leftreg,reservist,preg_occ,housingneeds,housingneeds_type,housingneeds_a,housingneeds_b,housingneeds_c,housingneeds_f,housingneeds_g,housingneeds_h,housingneeds_other,illness,illness_type_4,illness_type_5,illness_type_2,illness_type_6,illness_type_7,illness_type_3,illness_type_9,illness_type_8,illness_type_1,illness_type_10,layear,waityear,reason,reasonother,prevten,homeless,ppcodenk,ppostcode_full,prevloc_label,reasonpref,rp_homeless,rp_insan_unsat,rp_medwel,rp_hardship,rp_dontknow,cbl,cap,chr,letting_allocation_none,referral,referral_value_check,incref,earnings,incfreq,hb,has_benefits,benefits,household_charge,nocharge,period,is_carehome,chcharge,wchchrg,carehome_charges_value_check,brent,scharge,pscharge,supcharg,tcharge,scharge_value_check,pscharge_value_check,supcharg_value_check,hbrentshortfall,tshortfall,scheme_code,scheme_service_name,scheme_sensitive,SCHTYPE,scheme_registered_under_care_act,scheme_owning_organisation_name,scheme_primary_client_group,scheme_has_other_client_group,scheme_secondary_client_group,scheme_support_type,scheme_intended_stay,scheme_created_at,location_code,location_postcode,location_name,location_units,location_type_of_unit,location_mobility_type,location_local_authority,location_startdate id,status,duplicate_set_id,created_by,is_dpo,created_at,updated_by,updated_at,creation_method,collection_start_year,owning_organisation_name,managing_organisation_name,needstype,lettype,renewal,startdate,renttype,renttype_detail,irproduct,irproduct_other,lar,tenancycode,propcode,uprn_known,uprn,address_line1,address_line2,town_or_city,county,postcode_full,la_label,unitletas,rsnvac,newprop,offered,unittype_gn,builtype,wchair,beds,voiddate,vacdays,void_date_value_check,majorrepairs,mrcdate,major_repairs_date_value_check,joint,startertenancy,tenancy,tenancyother,tenancylength,sheltered,declaration,hhmemb,refused,age1,sex1,ethnic_group,ethnic,nationality_all,national,ecstat1,relat2,age2,sex2,ecstat2,relat3,age3,sex3,ecstat3,relat4,age4,sex4,ecstat4,relat5,age5,sex5,ecstat5,relat6,age6,sex6,ecstat6,relat7,age7,sex7,ecstat7,relat8,age8,sex8,ecstat8,armedforces,leftreg,reservist,preg_occ,housingneeds,housingneeds_type,housingneeds_a,housingneeds_b,housingneeds_c,housingneeds_f,housingneeds_g,housingneeds_h,housingneeds_other,illness,illness_type_4,illness_type_5,illness_type_2,illness_type_6,illness_type_7,illness_type_3,illness_type_9,illness_type_8,illness_type_1,illness_type_10,layear,waityear,reason,reasonother,prevten,homeless,ppcodenk,ppostcode_full,prevloc_label,reasonpref,rp_homeless,rp_insan_unsat,rp_medwel,rp_hardship,rp_dontknow,cbl,cap,chr,letting_allocation_none,referral,referral_value_check,incref,earnings,incfreq,hb,has_benefits,benefits,household_charge,nocharge,period,is_carehome,chcharge,wchchrg,carehome_charges_value_check,brent,scharge,pscharge,supcharg,tcharge,scharge_value_check,pscharge_value_check,supcharg_value_check,hbrentshortfall,tshortfall,scheme_code,scheme_service_name,scheme_sensitive,SCHTYPE,scheme_registered_under_care_act,scheme_owning_organisation_name,scheme_primary_client_group,scheme_has_other_client_group,scheme_secondary_client_group,scheme_support_type,scheme_intended_stay,scheme_created_at,location_code,location_postcode,location_name,location_units,location_type_of_unit,location_mobility_type,location_local_authority,location_startdate
,completed,,choreographer@owtluk.com,false,2023-11-26T00:00:00+00:00,,2023-11-26T00:00:00+00:00,1,2023,DLUHC,DLUHC,1,7,0,2023-11-26,2,2,1,,2,HIJKLMN,ABCDEFG,0,,fake address,,London,,NW9 5LL,Barnet,2,6,2,2,7,1,1,3,2023-11-24,1,,1,2023-11-25,,3,1,4,,2,,1,4,1,35,F,0,2,13,,0,P,32,M,6,R,-9,R,10,R,-9,R,10,,,,,,,,,,,,,,,,,1,4,1,2,1,0,1,0,0,0,0,0,0,1,0,0,1,0,0,0,0,0,0,0,2,7,4,,6,1,0,TN23 6LZ,Ashford,1,0,1,0,0,0,0,0,1,,2,,0,268,1,6,1,1,,0,2,,,,,200.0,50.0,40.0,35.0,325.0,,,,1,12.0,,,,,,,,,,,,,,,,,,,, ,completed,,choreographer@owtluk.com,false,2023-11-26T00:00:00+00:00,,2023-11-26T00:00:00+00:00,1,2023,DLUHC,DLUHC,1,7,0,2023-11-26,2,2,1,,2,HIJKLMN,ABCDEFG,0,,fake address,,London,,NW9 5LL,Barnet,2,6,2,2,7,1,1,3,2023-11-24,1,,1,2023-11-25,,3,1,4,,2,,1,4,1,35,F,0,2,,13,0,P,32,M,6,R,-9,R,10,R,-9,R,10,,,,,,,,,,,,,,,,,1,4,1,2,1,0,1,0,0,0,0,0,0,1,0,0,1,0,0,0,0,0,0,0,2,7,4,,6,1,0,TN23 6LZ,Ashford,1,0,1,0,0,0,0,0,1,,2,,0,268,1,6,1,1,,0,2,,,,,200.0,50.0,40.0,35.0,325.0,,,,1,12.0,,,,,,,,,,,,,,,,,,,,
1 id status duplicate_set_id created_by is_dpo created_at updated_by updated_at creation_method collection_start_year owning_organisation_name managing_organisation_name needstype lettype renewal startdate renttype renttype_detail irproduct irproduct_other lar tenancycode propcode uprn_known uprn address_line1 address_line2 town_or_city county postcode_full la_label unitletas rsnvac newprop offered unittype_gn builtype wchair beds voiddate vacdays void_date_value_check majorrepairs mrcdate major_repairs_date_value_check joint startertenancy tenancy tenancyother tenancylength sheltered declaration hhmemb refused age1 sex1 ethnic_group ethnic nationality_all national ecstat1 relat2 age2 sex2 ecstat2 relat3 age3 sex3 ecstat3 relat4 age4 sex4 ecstat4 relat5 age5 sex5 ecstat5 relat6 age6 sex6 ecstat6 relat7 age7 sex7 ecstat7 relat8 age8 sex8 ecstat8 armedforces leftreg reservist preg_occ housingneeds housingneeds_type housingneeds_a housingneeds_b housingneeds_c housingneeds_f housingneeds_g housingneeds_h housingneeds_other illness illness_type_4 illness_type_5 illness_type_2 illness_type_6 illness_type_7 illness_type_3 illness_type_9 illness_type_8 illness_type_1 illness_type_10 layear waityear reason reasonother prevten homeless ppcodenk ppostcode_full prevloc_label reasonpref rp_homeless rp_insan_unsat rp_medwel rp_hardship rp_dontknow cbl cap chr letting_allocation_none referral referral_value_check incref earnings incfreq hb has_benefits benefits household_charge nocharge period is_carehome chcharge wchchrg carehome_charges_value_check brent scharge pscharge supcharg tcharge scharge_value_check pscharge_value_check supcharg_value_check hbrentshortfall tshortfall scheme_code scheme_service_name scheme_sensitive SCHTYPE scheme_registered_under_care_act scheme_owning_organisation_name scheme_primary_client_group scheme_has_other_client_group scheme_secondary_client_group scheme_support_type scheme_intended_stay scheme_created_at location_code location_postcode location_name location_units location_type_of_unit location_mobility_type location_local_authority location_startdate
2 completed choreographer@owtluk.com false 2023-11-26T00:00:00+00:00 2023-11-26T00:00:00+00:00 1 2023 DLUHC DLUHC 1 7 0 2023-11-26 2 2 1 2 HIJKLMN ABCDEFG 0 fake address London NW9 5LL Barnet 2 6 2 2 7 1 1 3 2023-11-24 1 1 2023-11-25 3 1 4 2 1 4 1 35 F 0 2 13 0 P 32 M 6 R -9 R 10 R -9 R 10 1 4 1 2 1 0 1 0 0 0 0 0 0 1 0 0 1 0 0 0 0 0 0 0 2 7 4 6 1 0 TN23 6LZ Ashford 1 0 1 0 0 0 0 0 1 2 0 268 1 6 1 1 0 2 200.0 50.0 40.0 35.0 325.0 1 12.0

2
spec/fixtures/files/lettings_log_csv_export_non_support_codes_24.csv vendored

@ -0,0 +1,2 @@
id,status,duplicate_set_id,created_by,is_dpo,created_at,updated_by,updated_at,creation_method,collection_start_year,owning_organisation_name,managing_organisation_name,needstype,lettype,renewal,startdate,renttype,renttype_detail,irproduct,irproduct_other,lar,tenancycode,propcode,declaration,uprn_known,uprn,address_line1,address_line2,town_or_city,county,postcode_full,la_label,unitletas,rsnvac,newprop,offered,unittype_gn,builtype,wchair,beds,voiddate,vacdays,void_date_value_check,majorrepairs,mrcdate,major_repairs_date_value_check,joint,startertenancy,tenancy,tenancyother,tenancylength,sheltered,hhmemb,refused,age1,sex1,ethnic_group,ethnic,national,nationality_all,ecstat1,relat2,age2,sex2,ecstat2,relat3,age3,sex3,ecstat3,relat4,age4,sex4,ecstat4,relat5,age5,sex5,ecstat5,relat6,age6,sex6,ecstat6,relat7,age7,sex7,ecstat7,relat8,age8,sex8,ecstat8,armedforces,leftreg,reservist,preg_occ,housingneeds,housingneeds_type,housingneeds_a,housingneeds_b,housingneeds_c,housingneeds_f,housingneeds_g,housingneeds_h,housingneeds_other,illness,illness_type_4,illness_type_5,illness_type_2,illness_type_6,illness_type_7,illness_type_3,illness_type_9,illness_type_8,illness_type_1,illness_type_10,layear,waityear,reason,reasonother,prevten,homeless,ppcodenk,ppostcode_full,prevloc_label,reasonpref,rp_homeless,rp_insan_unsat,rp_medwel,rp_hardship,rp_dontknow,cbl,cap,chr,accessible_register,letting_allocation_none,referral,referral_value_check,incref,earnings,incfreq,hb,has_benefits,benefits,household_charge,nocharge,period,is_carehome,chcharge,wchchrg,carehome_charges_value_check,brent,scharge,pscharge,supcharg,tcharge,scharge_value_check,pscharge_value_check,supcharg_value_check,hbrentshortfall,tshortfall,scheme_code,scheme_service_name,scheme_sensitive,SCHTYPE,scheme_registered_under_care_act,scheme_owning_organisation_name,scheme_primary_client_group,scheme_has_other_client_group,scheme_secondary_client_group,scheme_support_type,scheme_intended_stay,scheme_created_at,location_code,location_postcode,location_name,location_units,location_type_of_unit,location_mobility_type,location_local_authority,location_startdate
,completed,,choreographer@owtluk.com,false,2023-11-26T00:00:00+00:00,,2024-04-01T00:00:00+01:00,1,2023,DLUHC,DLUHC,1,7,0,2023-11-26,2,2,1,,2,HIJKLMN,ABCDEFG,1,0,,fake address,,London,,NW9 5LL,Barnet,2,6,2,2,7,1,1,3,2023-11-24,1,,1,2023-11-25,,3,1,4,,2,,4,1,35,F,0,2,13,,0,P,32,M,6,R,-9,R,10,R,-9,R,10,,,,,,,,,,,,,,,,,1,4,1,2,1,0,1,0,0,0,0,0,0,1,0,0,1,0,0,0,0,0,0,0,2,7,4,,6,1,0,TN23 6LZ,Ashford,1,0,1,0,0,0,0,0,1,0,,2,,0,268,1,6,1,1,,0,2,,,,,200.0,50.0,40.0,35.0,325.0,,,,1,12.0,,,,,,,,,,,,,,,,,,,,
1 id status duplicate_set_id created_by is_dpo created_at updated_by updated_at creation_method collection_start_year owning_organisation_name managing_organisation_name needstype lettype renewal startdate renttype renttype_detail irproduct irproduct_other lar tenancycode propcode declaration uprn_known uprn address_line1 address_line2 town_or_city county postcode_full la_label unitletas rsnvac newprop offered unittype_gn builtype wchair beds voiddate vacdays void_date_value_check majorrepairs mrcdate major_repairs_date_value_check joint startertenancy tenancy tenancyother tenancylength sheltered hhmemb refused age1 sex1 ethnic_group ethnic national nationality_all ecstat1 relat2 age2 sex2 ecstat2 relat3 age3 sex3 ecstat3 relat4 age4 sex4 ecstat4 relat5 age5 sex5 ecstat5 relat6 age6 sex6 ecstat6 relat7 age7 sex7 ecstat7 relat8 age8 sex8 ecstat8 armedforces leftreg reservist preg_occ housingneeds housingneeds_type housingneeds_a housingneeds_b housingneeds_c housingneeds_f housingneeds_g housingneeds_h housingneeds_other illness illness_type_4 illness_type_5 illness_type_2 illness_type_6 illness_type_7 illness_type_3 illness_type_9 illness_type_8 illness_type_1 illness_type_10 layear waityear reason reasonother prevten homeless ppcodenk ppostcode_full prevloc_label reasonpref rp_homeless rp_insan_unsat rp_medwel rp_hardship rp_dontknow cbl cap chr accessible_register letting_allocation_none referral referral_value_check incref earnings incfreq hb has_benefits benefits household_charge nocharge period is_carehome chcharge wchchrg carehome_charges_value_check brent scharge pscharge supcharg tcharge scharge_value_check pscharge_value_check supcharg_value_check hbrentshortfall tshortfall scheme_code scheme_service_name scheme_sensitive SCHTYPE scheme_registered_under_care_act scheme_owning_organisation_name scheme_primary_client_group scheme_has_other_client_group scheme_secondary_client_group scheme_support_type scheme_intended_stay scheme_created_at location_code location_postcode location_name location_units location_type_of_unit location_mobility_type location_local_authority location_startdate
2 completed choreographer@owtluk.com false 2023-11-26T00:00:00+00:00 2024-04-01T00:00:00+01:00 1 2023 DLUHC DLUHC 1 7 0 2023-11-26 2 2 1 2 HIJKLMN ABCDEFG 1 0 fake address London NW9 5LL Barnet 2 6 2 2 7 1 1 3 2023-11-24 1 1 2023-11-25 3 1 4 2 4 1 35 F 0 2 13 0 P 32 M 6 R -9 R 10 R -9 R 10 1 4 1 2 1 0 1 0 0 0 0 0 0 1 0 0 1 0 0 0 0 0 0 0 2 7 4 6 1 0 TN23 6LZ Ashford 1 0 1 0 0 0 0 0 1 0 2 0 268 1 6 1 1 0 2 200.0 50.0 40.0 35.0 325.0 1 12.0

4
spec/fixtures/files/lettings_log_csv_export_non_support_labels.csv → spec/fixtures/files/lettings_log_csv_export_non_support_labels_23.csv vendored

@ -1,2 +1,2 @@
id,status,duplicate_set_id,created_by,is_dpo,created_at,updated_by,updated_at,creation_method,collection_start_year,owning_organisation_name,managing_organisation_name,needstype,lettype,renewal,startdate,renttype,renttype_detail,irproduct,irproduct_other,lar,tenancycode,propcode,uprn_known,uprn,address_line1,address_line2,town_or_city,county,postcode_full,la_label,unitletas,rsnvac,newprop,offered,unittype_gn,builtype,wchair,beds,voiddate,vacdays,void_date_value_check,majorrepairs,mrcdate,major_repairs_date_value_check,joint,startertenancy,tenancy,tenancyother,tenancylength,sheltered,declaration,hhmemb,refused,age1,sex1,ethnic_group,ethnic,national,nationality_all,ecstat1,relat2,age2,sex2,ecstat2,relat3,age3,sex3,ecstat3,relat4,age4,sex4,ecstat4,relat5,age5,sex5,ecstat5,relat6,age6,sex6,ecstat6,relat7,age7,sex7,ecstat7,relat8,age8,sex8,ecstat8,armedforces,leftreg,reservist,preg_occ,housingneeds,housingneeds_type,housingneeds_a,housingneeds_b,housingneeds_c,housingneeds_f,housingneeds_g,housingneeds_h,housingneeds_other,illness,illness_type_4,illness_type_5,illness_type_2,illness_type_6,illness_type_7,illness_type_3,illness_type_9,illness_type_8,illness_type_1,illness_type_10,layear,waityear,reason,reasonother,prevten,homeless,ppcodenk,ppostcode_full,prevloc_label,reasonpref,rp_homeless,rp_insan_unsat,rp_medwel,rp_hardship,rp_dontknow,cbl,cap,chr,letting_allocation_none,referral,referral_value_check,incref,earnings,incfreq,hb,has_benefits,benefits,household_charge,nocharge,period,is_carehome,chcharge,wchchrg,carehome_charges_value_check,brent,scharge,pscharge,supcharg,tcharge,scharge_value_check,pscharge_value_check,supcharg_value_check,hbrentshortfall,tshortfall,scheme_code,scheme_service_name,scheme_sensitive,SCHTYPE,scheme_registered_under_care_act,scheme_owning_organisation_name,scheme_primary_client_group,scheme_has_other_client_group,scheme_secondary_client_group,scheme_support_type,scheme_intended_stay,scheme_created_at,location_code,location_postcode,location_name,location_units,location_type_of_unit,location_mobility_type,location_local_authority,location_startdate id,status,duplicate_set_id,created_by,is_dpo,created_at,updated_by,updated_at,creation_method,collection_start_year,owning_organisation_name,managing_organisation_name,needstype,lettype,renewal,startdate,renttype,renttype_detail,irproduct,irproduct_other,lar,tenancycode,propcode,uprn_known,uprn,address_line1,address_line2,town_or_city,county,postcode_full,la_label,unitletas,rsnvac,newprop,offered,unittype_gn,builtype,wchair,beds,voiddate,vacdays,void_date_value_check,majorrepairs,mrcdate,major_repairs_date_value_check,joint,startertenancy,tenancy,tenancyother,tenancylength,sheltered,declaration,hhmemb,refused,age1,sex1,ethnic_group,ethnic,nationality_all,national,ecstat1,relat2,age2,sex2,ecstat2,relat3,age3,sex3,ecstat3,relat4,age4,sex4,ecstat4,relat5,age5,sex5,ecstat5,relat6,age6,sex6,ecstat6,relat7,age7,sex7,ecstat7,relat8,age8,sex8,ecstat8,armedforces,leftreg,reservist,preg_occ,housingneeds,housingneeds_type,housingneeds_a,housingneeds_b,housingneeds_c,housingneeds_f,housingneeds_g,housingneeds_h,housingneeds_other,illness,illness_type_4,illness_type_5,illness_type_2,illness_type_6,illness_type_7,illness_type_3,illness_type_9,illness_type_8,illness_type_1,illness_type_10,layear,waityear,reason,reasonother,prevten,homeless,ppcodenk,ppostcode_full,prevloc_label,reasonpref,rp_homeless,rp_insan_unsat,rp_medwel,rp_hardship,rp_dontknow,cbl,cap,chr,letting_allocation_none,referral,referral_value_check,incref,earnings,incfreq,hb,has_benefits,benefits,household_charge,nocharge,period,is_carehome,chcharge,wchchrg,carehome_charges_value_check,brent,scharge,pscharge,supcharg,tcharge,scharge_value_check,pscharge_value_check,supcharg_value_check,hbrentshortfall,tshortfall,scheme_code,scheme_service_name,scheme_sensitive,SCHTYPE,scheme_registered_under_care_act,scheme_owning_organisation_name,scheme_primary_client_group,scheme_has_other_client_group,scheme_secondary_client_group,scheme_support_type,scheme_intended_stay,scheme_created_at,location_code,location_postcode,location_name,location_units,location_type_of_unit,location_mobility_type,location_local_authority,location_startdate
,completed,,choreographer@owtluk.com,false,2023-11-26T00:00:00+00:00,,2023-11-26T00:00:00+00:00,single log,2023,DLUHC,DLUHC,General needs,Affordable rent general needs local authority,No,2023-11-26,Affordable Rent,Affordable Rent,Rent to Buy,,No,HIJKLMN,ABCDEFG,No,,fake address,,London,,NW9 5LL,Barnet,Affordable rent basis,Tenant abandoned property,No,2,House,Purpose built,Yes,3,2023-11-24,1,,Yes,2023-11-25,,Don’t know,Yes,Assured Shorthold Tenancy (AST) – Fixed term,,2,,Yes,4,Yes,35,Female,White,Irish,Tenant prefers not to say,,Other,Partner,32,Male,Not seeking work,Prefers not to say,Not known,Prefers not to say,Prefers not to say,Person prefers not to say,Not known,Person prefers not to say,Person prefers not to say,,,,,,,,,,,,,,,,,Yes – the person is a current or former regular,No – they left up to and including 5 years ago,Yes,No,Yes,Fully wheelchair accessible housing,Yes,No,No,No,No,No,No,Yes,No,No,Yes,No,No,No,No,No,No,No,Less than 1 year,1 year but under 2 years,Loss of tied accommodation,,Other supported housing,No,Yes,TN23 6LZ,Ashford,Yes,,Yes,,,,No,No,Yes,,Tenant applied directly (no referral or nomination),,No,268,Weekly,Universal Credit housing element,Yes,All,,No,Every 2 weeks,,,,,200.0,50.0,40.0,35.0,325.0,,,,Yes,12.0,,,,,,,,,,,,,,,,,,,, ,completed,,choreographer@owtluk.com,false,2023-11-26T00:00:00+00:00,,2023-11-26T00:00:00+00:00,single log,2023,DLUHC,DLUHC,General needs,Affordable rent general needs local authority,No,2023-11-26,Affordable Rent,Affordable Rent,Rent to Buy,,No,HIJKLMN,ABCDEFG,No,,fake address,,London,,NW9 5LL,Barnet,Affordable rent basis,Tenant abandoned property,No,2,House,Purpose built,Yes,3,2023-11-24,1,,Yes,2023-11-25,,Don’t know,Yes,Assured Shorthold Tenancy (AST) – Fixed term,,2,,Yes,4,Yes,35,Female,White,Irish,,Tenant prefers not to say,Other,Partner,32,Male,Not seeking work,Prefers not to say,Not known,Prefers not to say,Prefers not to say,Person prefers not to say,Not known,Person prefers not to say,Person prefers not to say,,,,,,,,,,,,,,,,,Yes – the person is a current or former regular,No – they left up to and including 5 years ago,Yes,No,Yes,Fully wheelchair accessible housing,Yes,No,No,No,No,No,No,Yes,No,No,Yes,No,No,No,No,No,No,No,Less than 1 year,1 year but under 2 years,Loss of tied accommodation,,Other supported housing,No,Yes,TN23 6LZ,Ashford,Yes,,Yes,,,,No,No,Yes,,Tenant applied directly (no referral or nomination),,No,268,Weekly,Universal Credit housing element,Yes,All,,No,Every 2 weeks,,,,,200.0,50.0,40.0,35.0,325.0,,,,Yes,12.0,,,,,,,,,,,,,,,,,,,,
1 id status duplicate_set_id created_by is_dpo created_at updated_by updated_at creation_method collection_start_year owning_organisation_name managing_organisation_name needstype lettype renewal startdate renttype renttype_detail irproduct irproduct_other lar tenancycode propcode uprn_known uprn address_line1 address_line2 town_or_city county postcode_full la_label unitletas rsnvac newprop offered unittype_gn builtype wchair beds voiddate vacdays void_date_value_check majorrepairs mrcdate major_repairs_date_value_check joint startertenancy tenancy tenancyother tenancylength sheltered declaration hhmemb refused age1 sex1 ethnic_group ethnic nationality_all national ecstat1 relat2 age2 sex2 ecstat2 relat3 age3 sex3 ecstat3 relat4 age4 sex4 ecstat4 relat5 age5 sex5 ecstat5 relat6 age6 sex6 ecstat6 relat7 age7 sex7 ecstat7 relat8 age8 sex8 ecstat8 armedforces leftreg reservist preg_occ housingneeds housingneeds_type housingneeds_a housingneeds_b housingneeds_c housingneeds_f housingneeds_g housingneeds_h housingneeds_other illness illness_type_4 illness_type_5 illness_type_2 illness_type_6 illness_type_7 illness_type_3 illness_type_9 illness_type_8 illness_type_1 illness_type_10 layear waityear reason reasonother prevten homeless ppcodenk ppostcode_full prevloc_label reasonpref rp_homeless rp_insan_unsat rp_medwel rp_hardship rp_dontknow cbl cap chr letting_allocation_none referral referral_value_check incref earnings incfreq hb has_benefits benefits household_charge nocharge period is_carehome chcharge wchchrg carehome_charges_value_check brent scharge pscharge supcharg tcharge scharge_value_check pscharge_value_check supcharg_value_check hbrentshortfall tshortfall scheme_code scheme_service_name scheme_sensitive SCHTYPE scheme_registered_under_care_act scheme_owning_organisation_name scheme_primary_client_group scheme_has_other_client_group scheme_secondary_client_group scheme_support_type scheme_intended_stay scheme_created_at location_code location_postcode location_name location_units location_type_of_unit location_mobility_type location_local_authority location_startdate
2 completed choreographer@owtluk.com false 2023-11-26T00:00:00+00:00 2023-11-26T00:00:00+00:00 single log 2023 DLUHC DLUHC General needs Affordable rent general needs local authority No 2023-11-26 Affordable Rent Affordable Rent Rent to Buy No HIJKLMN ABCDEFG No fake address London NW9 5LL Barnet Affordable rent basis Tenant abandoned property No 2 House Purpose built Yes 3 2023-11-24 1 Yes 2023-11-25 Don’t know Yes Assured Shorthold Tenancy (AST) – Fixed term 2 Yes 4 Yes 35 Female White Irish Tenant prefers not to say Other Partner 32 Male Not seeking work Prefers not to say Not known Prefers not to say Prefers not to say Person prefers not to say Not known Person prefers not to say Person prefers not to say Yes – the person is a current or former regular No – they left up to and including 5 years ago Yes No Yes Fully wheelchair accessible housing Yes No No No No No No Yes No No Yes No No No No No No No Less than 1 year 1 year but under 2 years Loss of tied accommodation Other supported housing No Yes TN23 6LZ Ashford Yes Yes No No Yes Tenant applied directly (no referral or nomination) No 268 Weekly Universal Credit housing element Yes All No Every 2 weeks 200.0 50.0 40.0 35.0 325.0 Yes 12.0

2
spec/fixtures/files/lettings_log_csv_export_non_support_labels_24.csv vendored

@ -0,0 +1,2 @@
id,status,duplicate_set_id,created_by,is_dpo,created_at,updated_by,updated_at,creation_method,collection_start_year,owning_organisation_name,managing_organisation_name,needstype,lettype,renewal,startdate,renttype,renttype_detail,irproduct,irproduct_other,lar,tenancycode,propcode,declaration,uprn_known,uprn,address_line1,address_line2,town_or_city,county,postcode_full,la_label,unitletas,rsnvac,newprop,offered,unittype_gn,builtype,wchair,beds,voiddate,vacdays,void_date_value_check,majorrepairs,mrcdate,major_repairs_date_value_check,joint,startertenancy,tenancy,tenancyother,tenancylength,sheltered,hhmemb,refused,age1,sex1,ethnic_group,ethnic,national,nationality_all,ecstat1,relat2,age2,sex2,ecstat2,relat3,age3,sex3,ecstat3,relat4,age4,sex4,ecstat4,relat5,age5,sex5,ecstat5,relat6,age6,sex6,ecstat6,relat7,age7,sex7,ecstat7,relat8,age8,sex8,ecstat8,armedforces,leftreg,reservist,preg_occ,housingneeds,housingneeds_type,housingneeds_a,housingneeds_b,housingneeds_c,housingneeds_f,housingneeds_g,housingneeds_h,housingneeds_other,illness,illness_type_4,illness_type_5,illness_type_2,illness_type_6,illness_type_7,illness_type_3,illness_type_9,illness_type_8,illness_type_1,illness_type_10,layear,waityear,reason,reasonother,prevten,homeless,ppcodenk,ppostcode_full,prevloc_label,reasonpref,rp_homeless,rp_insan_unsat,rp_medwel,rp_hardship,rp_dontknow,cbl,cap,chr,accessible_register,letting_allocation_none,referral,referral_value_check,incref,earnings,incfreq,hb,has_benefits,benefits,household_charge,nocharge,period,is_carehome,chcharge,wchchrg,carehome_charges_value_check,brent,scharge,pscharge,supcharg,tcharge,scharge_value_check,pscharge_value_check,supcharg_value_check,hbrentshortfall,tshortfall,scheme_code,scheme_service_name,scheme_sensitive,SCHTYPE,scheme_registered_under_care_act,scheme_owning_organisation_name,scheme_primary_client_group,scheme_has_other_client_group,scheme_secondary_client_group,scheme_support_type,scheme_intended_stay,scheme_created_at,location_code,location_postcode,location_name,location_units,location_type_of_unit,location_mobility_type,location_local_authority,location_startdate
,completed,,choreographer@owtluk.com,false,2023-11-26T00:00:00+00:00,,2024-04-01T00:00:00+01:00,single log,2023,DLUHC,DLUHC,General needs,Affordable rent general needs local authority,No,2023-11-26,Affordable Rent,Affordable Rent,Rent to Buy,,No,HIJKLMN,ABCDEFG,Yes,No,,fake address,,London,,NW9 5LL,Barnet,Affordable rent basis,Tenant abandoned property,No,2,House,Purpose built,Yes,3,2023-11-24,1,,Yes,2023-11-25,,Don’t know,Yes,Assured Shorthold Tenancy (AST) – Fixed term,,2,,4,Yes,35,Female,White,Irish,Tenant prefers not to say,,Other,Partner,32,Male,Not seeking work,Prefers not to say,Not known,Prefers not to say,Prefers not to say,Person prefers not to say,Not known,Person prefers not to say,Person prefers not to say,,,,,,,,,,,,,,,,,Yes – the person is a current or former regular,No – they left up to and including 5 years ago,Yes,No,Yes,Fully wheelchair accessible housing,Yes,No,No,No,No,No,No,Yes,No,No,Yes,No,No,No,No,No,No,No,Less than 1 year,1 year but under 2 years,Loss of tied accommodation,,Other supported housing,No,Yes,TN23 6LZ,Ashford,Yes,,Yes,,,,No,No,Yes,No,,Tenant applied directly (no referral or nomination),,No,268,Weekly,Universal Credit housing element,Yes,All,,No,Every 2 weeks,,,,,200.0,50.0,40.0,35.0,325.0,,,,Yes,12.0,,,,,,,,,,,,,,,,,,,,
1 id status duplicate_set_id created_by is_dpo created_at updated_by updated_at creation_method collection_start_year owning_organisation_name managing_organisation_name needstype lettype renewal startdate renttype renttype_detail irproduct irproduct_other lar tenancycode propcode declaration uprn_known uprn address_line1 address_line2 town_or_city county postcode_full la_label unitletas rsnvac newprop offered unittype_gn builtype wchair beds voiddate vacdays void_date_value_check majorrepairs mrcdate major_repairs_date_value_check joint startertenancy tenancy tenancyother tenancylength sheltered hhmemb refused age1 sex1 ethnic_group ethnic national nationality_all ecstat1 relat2 age2 sex2 ecstat2 relat3 age3 sex3 ecstat3 relat4 age4 sex4 ecstat4 relat5 age5 sex5 ecstat5 relat6 age6 sex6 ecstat6 relat7 age7 sex7 ecstat7 relat8 age8 sex8 ecstat8 armedforces leftreg reservist preg_occ housingneeds housingneeds_type housingneeds_a housingneeds_b housingneeds_c housingneeds_f housingneeds_g housingneeds_h housingneeds_other illness illness_type_4 illness_type_5 illness_type_2 illness_type_6 illness_type_7 illness_type_3 illness_type_9 illness_type_8 illness_type_1 illness_type_10 layear waityear reason reasonother prevten homeless ppcodenk ppostcode_full prevloc_label reasonpref rp_homeless rp_insan_unsat rp_medwel rp_hardship rp_dontknow cbl cap chr accessible_register letting_allocation_none referral referral_value_check incref earnings incfreq hb has_benefits benefits household_charge nocharge period is_carehome chcharge wchchrg carehome_charges_value_check brent scharge pscharge supcharg tcharge scharge_value_check pscharge_value_check supcharg_value_check hbrentshortfall tshortfall scheme_code scheme_service_name scheme_sensitive SCHTYPE scheme_registered_under_care_act scheme_owning_organisation_name scheme_primary_client_group scheme_has_other_client_group scheme_secondary_client_group scheme_support_type scheme_intended_stay scheme_created_at location_code location_postcode location_name location_units location_type_of_unit location_mobility_type location_local_authority location_startdate
2 completed choreographer@owtluk.com false 2023-11-26T00:00:00+00:00 2024-04-01T00:00:00+01:00 single log 2023 DLUHC DLUHC General needs Affordable rent general needs local authority No 2023-11-26 Affordable Rent Affordable Rent Rent to Buy No HIJKLMN ABCDEFG Yes No fake address London NW9 5LL Barnet Affordable rent basis Tenant abandoned property No 2 House Purpose built Yes 3 2023-11-24 1 Yes 2023-11-25 Don’t know Yes Assured Shorthold Tenancy (AST) – Fixed term 2 4 Yes 35 Female White Irish Tenant prefers not to say Other Partner 32 Male Not seeking work Prefers not to say Not known Prefers not to say Prefers not to say Person prefers not to say Not known Person prefers not to say Person prefers not to say Yes – the person is a current or former regular No – they left up to and including 5 years ago Yes No Yes Fully wheelchair accessible housing Yes No No No No No No Yes No No Yes No No No No No No No Less than 1 year 1 year but under 2 years Loss of tied accommodation Other supported housing No Yes TN23 6LZ Ashford Yes Yes No No Yes No Tenant applied directly (no referral or nomination) No 268 Weekly Universal Credit housing element Yes All No Every 2 weeks 200.0 50.0 40.0 35.0 325.0 Yes 12.0

2
spec/fixtures/files/sales_logs_csv_export_codes_23.csv vendored

@ -0,0 +1,2 @@
id,status,duplicate_set_id,created_at,updated_at,old_form_id,collection_start_year,creation_method,is_dpo,owning_organisation_name,managing_organisation_name,created_by,day,month,year,purchid,ownershipsch,type,othtype,companybuy,buylivein,jointpur,jointmore,beds,proptype,builtype,pcodenk,uprn,uprn_confirmed,address_line1,address_line2,town_or_city,county,pcode1,pcode2,la_known,la,la_label,wchair,noint,privacynotice,age1,sex1,ethnic_group,ethnic,nationality_all,national,ecstat1,buy1livein,relat2,age2,sex2,ethnic_group2,ethnicbuy2,nationality_all_buyer2,nationalbuy2,ecstat2,buy2livein,hholdcount,relat3,age3,sex3,ecstat3,relat4,age4,sex4,ecstat4,relat5,age5,sex5,ecstat5,relat6,age6,sex6,ecstat6,prevten,ppcodenk,ppostc1,ppostc2,previous_la_known,prevloc,prevloc_label,pregyrha,pregother,pregla,pregghb,pregblank,buy2living,prevtenbuy2,hhregres,hhregresstill,armedforcesspouse,disabled,wheel,income1nk,income1,inc1mort,income2nk,income2,inc2mort,hb,savingsnk,savings,prevown,prevshared,proplen,staircase,stairbought,stairowned,staircasesale,resale,exday,exmonth,exyear,hoday,homonth,hoyear,lanomagr,soctenant,frombeds,fromprop,socprevten,value,equity,mortgageused,mortgage,mortgagelender,mortgagelenderother,mortlen,extrabor,deposit,cashdis,mrent,has_mscharge,mscharge,discount,grant
,completed,,2023-12-08T00:00:00+00:00,2024-01-01T00:00:00+00:00,,2023,1,false,DLUHC,DLUHC,billyboy@eyeklaud.com,8,12,2023,,2,8,,,,1,1,2,1,1,0,,,Address line 1,,Town or city,,SW1A,1AA,1,E09000003,Barnet,1,2,1,30,X,17,17,,18,1,1,P,35,X,17,,,13,1,1,3,C,14,X,9,X,-9,X,3,R,-9,R,10,,,,,1,1,,,0,,,1,1,1,1,,3,,1,4,5,1,1,0,10000,1,0,10000,1,4,1,,1,2,10,,,,,,,,,,,,,,,,,110000.0,,1,20000.0,5,,10,1,80000.0,,,1,100.0,,10000.0
1 id status duplicate_set_id created_at updated_at old_form_id collection_start_year creation_method is_dpo owning_organisation_name managing_organisation_name created_by day month year purchid ownershipsch type othtype companybuy buylivein jointpur jointmore beds proptype builtype pcodenk uprn uprn_confirmed address_line1 address_line2 town_or_city county pcode1 pcode2 la_known la la_label wchair noint privacynotice age1 sex1 ethnic_group ethnic nationality_all national ecstat1 buy1livein relat2 age2 sex2 ethnic_group2 ethnicbuy2 nationality_all_buyer2 nationalbuy2 ecstat2 buy2livein hholdcount relat3 age3 sex3 ecstat3 relat4 age4 sex4 ecstat4 relat5 age5 sex5 ecstat5 relat6 age6 sex6 ecstat6 prevten ppcodenk ppostc1 ppostc2 previous_la_known prevloc prevloc_label pregyrha pregother pregla pregghb pregblank buy2living prevtenbuy2 hhregres hhregresstill armedforcesspouse disabled wheel income1nk income1 inc1mort income2nk income2 inc2mort hb savingsnk savings prevown prevshared proplen staircase stairbought stairowned staircasesale resale exday exmonth exyear hoday homonth hoyear lanomagr soctenant frombeds fromprop socprevten value equity mortgageused mortgage mortgagelender mortgagelenderother mortlen extrabor deposit cashdis mrent has_mscharge mscharge discount grant
2 completed 2023-12-08T00:00:00+00:00 2024-01-01T00:00:00+00:00 2023 1 false DLUHC DLUHC billyboy@eyeklaud.com 8 12 2023 2 8 1 1 2 1 1 0 Address line 1 Town or city SW1A 1AA 1 E09000003 Barnet 1 2 1 30 X 17 17 18 1 1 P 35 X 17 13 1 1 3 C 14 X 9 X -9 X 3 R -9 R 10 1 1 0 1 1 1 1 3 1 4 5 1 1 0 10000 1 0 10000 1 4 1 1 2 10 110000.0 1 20000.0 5 10 1 80000.0 1 100.0 10000.0

4
spec/fixtures/files/sales_logs_csv_export_codes.csv → spec/fixtures/files/sales_logs_csv_export_codes_24.csv vendored

@ -1,2 +1,2 @@
id,status,duplicate_set_id,created_at,updated_at,old_form_id,collection_start_year,creation_method,is_dpo,owning_organisation_name,managing_organisation_name,created_by,day,month,year,purchid,ownershipsch,type,othtype,companybuy,buylivein,jointpur,jointmore,noint,uprn,uprn_confirmed,address_line1,address_line2,town_or_city,county,pcode1,pcode2,la_known,la,la_label,beds,proptype,builtype,pcodenk,wchair,privacynotice,age1,sex1,ethnic_group,ethnic,national,nationality_all,ecstat1,buy1livein,relat2,age2,sex2,ethnic_group2,ethnicbuy2,nationalbuy2,nationality_all_buyer2,ecstat2,buy2livein,hholdcount,relat3,age3,sex3,ecstat3,relat4,age4,sex4,ecstat4,relat5,age5,sex5,ecstat5,relat6,age6,sex6,ecstat6,prevten,ppcodenk,ppostc1,ppostc2,previous_la_known,prevloc,prevloc_label,pregyrha,pregother,pregla,pregghb,pregblank,buy2living,prevtenbuy2,hhregres,hhregresstill,armedforcesspouse,disabled,wheel,income1nk,income1,inc1mort,income2nk,income2,inc2mort,hb,savingsnk,savings,prevown,prevshared,proplen,staircase,stairbought,stairowned,staircasesale,resale,exday,exmonth,exyear,hoday,homonth,hoyear,lanomagr,soctenant,frombeds,fromprop,socprevten,value,equity,mortgageused,mortgage,mortgagelender,mortgagelenderother,mortlen,extrabor,deposit,cashdis,mrent,has_mscharge,mscharge,discount,grant id,status,duplicate_set_id,created_at,updated_at,old_form_id,collection_start_year,creation_method,is_dpo,owning_organisation_name,managing_organisation_name,created_by,day,month,year,purchid,ownershipsch,type,othtype,companybuy,buylivein,jointpur,jointmore,noint,privacynotice,uprn,uprn_confirmed,address_line1,address_line2,town_or_city,county,pcode1,pcode2,la_known,la,la_label,beds,proptype,builtype,pcodenk,wchair,age1,sex1,ethnic_group,ethnic,national,nationality_all,ecstat1,buy1livein,relat2,age2,sex2,ethnic_group2,ethnicbuy2,nationalbuy2,nationality_all_buyer2,ecstat2,buy2livein,hholdcount,relat3,age3,sex3,ecstat3,relat4,age4,sex4,ecstat4,relat5,age5,sex5,ecstat5,relat6,age6,sex6,ecstat6,prevten,ppcodenk,ppostc1,ppostc2,previous_la_known,prevloc,prevloc_label,pregyrha,pregother,pregla,pregghb,pregblank,buy2living,prevtenbuy2,hhregres,hhregresstill,armedforcesspouse,disabled,wheel,income1nk,income1,inc1mort,income2nk,income2,inc2mort,hb,savingsnk,savings,prevown,prevshared,proplen,staircase,stairbought,stairowned,staircasesale,resale,exday,exmonth,exyear,hoday,homonth,hoyear,lanomagr,soctenant,frombeds,fromprop,socprevten,value,equity,mortgageused,mortgage,mortgagelender,mortgagelenderother,mortlen,extrabor,deposit,cashdis,mrent,has_mscharge,mscharge,discount,grant
,completed,,2023-12-08T00:00:00+00:00,2023-12-08T00:00:00+00:00,,2023,1,false,DLUHC,DLUHC,billyboy@eyeklaud.com,8,12,2023,,2,8,,,,1,1,2,,,Address line 1,,Town or city,,SW1A,1AA,1,E09000003,Barnet,2,1,1,0,1,1,30,X,17,17,18,,1,1,P,35,X,17,,13,,1,1,3,C,14,X,9,X,-9,X,3,R,-9,R,10,,,,,1,1,,,0,,,1,1,1,1,,3,,1,4,5,1,1,0,10000,1,0,10000,1,4,1,,1,2,10,,,,,,,,,,,,,,,,,110000.0,,1,20000.0,5,,10,1,80000.0,,,1,100.0,,10000.0 ,completed,,2023-12-08T00:00:00+00:00,2024-05-01T00:00:00+01:00,,2023,1,false,DLUHC,DLUHC,billyboy@eyeklaud.com,8,12,2023,,2,8,,,,1,1,2,1,,,Address line 1,,Town or city,,SW1A,1AA,1,E09000003,Barnet,2,1,1,0,1,30,X,17,17,18,,1,1,P,35,X,17,,13,,1,1,3,C,14,X,9,X,-9,X,3,R,-9,R,10,,,,,1,1,,,0,,,1,1,1,1,,3,,1,4,5,1,1,0,10000,1,0,10000,1,4,1,,1,2,10,,,,,,,,,,,,,,,,,110000.0,,1,20000.0,5,,10,1,80000.0,,,1,100.0,,10000.0
1 id status duplicate_set_id created_at updated_at old_form_id collection_start_year creation_method is_dpo owning_organisation_name managing_organisation_name created_by day month year purchid ownershipsch type othtype companybuy buylivein jointpur jointmore noint privacynotice uprn uprn_confirmed address_line1 address_line2 town_or_city county pcode1 pcode2 la_known la la_label beds proptype builtype pcodenk wchair age1 sex1 ethnic_group ethnic national nationality_all ecstat1 buy1livein relat2 age2 sex2 ethnic_group2 ethnicbuy2 nationalbuy2 nationality_all_buyer2 ecstat2 buy2livein hholdcount relat3 age3 sex3 ecstat3 relat4 age4 sex4 ecstat4 relat5 age5 sex5 ecstat5 relat6 age6 sex6 ecstat6 prevten ppcodenk ppostc1 ppostc2 previous_la_known prevloc prevloc_label pregyrha pregother pregla pregghb pregblank buy2living prevtenbuy2 hhregres hhregresstill armedforcesspouse disabled wheel income1nk income1 inc1mort income2nk income2 inc2mort hb savingsnk savings prevown prevshared proplen staircase stairbought stairowned staircasesale resale exday exmonth exyear hoday homonth hoyear lanomagr soctenant frombeds fromprop socprevten value equity mortgageused mortgage mortgagelender mortgagelenderother mortlen extrabor deposit cashdis mrent has_mscharge mscharge discount grant
2 completed 2023-12-08T00:00:00+00:00 2024-05-01T00:00:00+01:00 2023 1 false DLUHC DLUHC billyboy@eyeklaud.com 8 12 2023 2 8 1 1 2 1 Address line 1 Town or city SW1A 1AA 1 E09000003 Barnet 2 1 1 0 1 30 X 17 17 18 1 1 P 35 X 17 13 1 1 3 C 14 X 9 X -9 X 3 R -9 R 10 1 1 0 1 1 1 1 3 1 4 5 1 1 0 10000 1 0 10000 1 4 1 1 2 10 110000.0 1 20000.0 5 10 1 80000.0 1 100.0 10000.0

2
spec/fixtures/files/sales_logs_csv_export_labels_23.csv vendored

@ -0,0 +1,2 @@
id,status,duplicate_set_id,created_at,updated_at,old_form_id,collection_start_year,creation_method,is_dpo,owning_organisation_name,managing_organisation_name,created_by,day,month,year,purchid,ownershipsch,type,othtype,companybuy,buylivein,jointpur,jointmore,beds,proptype,builtype,pcodenk,uprn,uprn_confirmed,address_line1,address_line2,town_or_city,county,pcode1,pcode2,la_known,la,la_label,wchair,noint,privacynotice,age1,sex1,ethnic_group,ethnic,nationality_all,national,ecstat1,buy1livein,relat2,age2,sex2,ethnic_group2,ethnicbuy2,nationality_all_buyer2,nationalbuy2,ecstat2,buy2livein,hholdcount,relat3,age3,sex3,ecstat3,relat4,age4,sex4,ecstat4,relat5,age5,sex5,ecstat5,relat6,age6,sex6,ecstat6,prevten,ppcodenk,ppostc1,ppostc2,previous_la_known,prevloc,prevloc_label,pregyrha,pregother,pregla,pregghb,pregblank,buy2living,prevtenbuy2,hhregres,hhregresstill,armedforcesspouse,disabled,wheel,income1nk,income1,inc1mort,income2nk,income2,inc2mort,hb,savingsnk,savings,prevown,prevshared,proplen,staircase,stairbought,stairowned,staircasesale,resale,exday,exmonth,exyear,hoday,homonth,hoyear,lanomagr,soctenant,frombeds,fromprop,socprevten,value,equity,mortgageused,mortgage,mortgagelender,mortgagelenderother,mortlen,extrabor,deposit,cashdis,mrent,has_mscharge,mscharge,discount,grant
,completed,,2023-12-08T00:00:00+00:00,2024-01-01T00:00:00+00:00,,2023,single log,false,DLUHC,DLUHC,billyboy@eyeklaud.com,8,12,2023,,Yes - a discounted ownership scheme,Right to Acquire (RTA),,,,Yes,Yes,2,Flat or maisonette,Purpose built,0,,,Address line 1,,Town or city,,SW1A,1AA,1,E09000003,Barnet,Yes,Yes,1,30,Non-binary,Buyer 1 prefers not to say,17,,United Kingdom,Full-time - 30 hours or more,Yes,Partner,35,Non-binary,Buyer 2 prefers not to say,,,Buyer prefers not to say,Full-time - 30 hours or more,Yes,3,Child,14,Non-binary,Child under 16,Other,Not known,Non-binary,"In government training into work, such as New Deal",Prefers not to say,Not known,Prefers not to say,Prefers not to say,,,,,Local authority tenant,No,,,No,,,1,1,1,1,,Don't know,,Yes,Yes,No,Yes,Yes,Yes,10000,Yes,Yes,10000,Yes,"Don’t know ",No,,Yes,No,10,,,,,,,,,,,,,,,,,110000.0,,Yes,20000.0,Cambridge Building Society,,10,Yes,80000.0,,,Yes,100.0,,10000.0
1 id status duplicate_set_id created_at updated_at old_form_id collection_start_year creation_method is_dpo owning_organisation_name managing_organisation_name created_by day month year purchid ownershipsch type othtype companybuy buylivein jointpur jointmore beds proptype builtype pcodenk uprn uprn_confirmed address_line1 address_line2 town_or_city county pcode1 pcode2 la_known la la_label wchair noint privacynotice age1 sex1 ethnic_group ethnic nationality_all national ecstat1 buy1livein relat2 age2 sex2 ethnic_group2 ethnicbuy2 nationality_all_buyer2 nationalbuy2 ecstat2 buy2livein hholdcount relat3 age3 sex3 ecstat3 relat4 age4 sex4 ecstat4 relat5 age5 sex5 ecstat5 relat6 age6 sex6 ecstat6 prevten ppcodenk ppostc1 ppostc2 previous_la_known prevloc prevloc_label pregyrha pregother pregla pregghb pregblank buy2living prevtenbuy2 hhregres hhregresstill armedforcesspouse disabled wheel income1nk income1 inc1mort income2nk income2 inc2mort hb savingsnk savings prevown prevshared proplen staircase stairbought stairowned staircasesale resale exday exmonth exyear hoday homonth hoyear lanomagr soctenant frombeds fromprop socprevten value equity mortgageused mortgage mortgagelender mortgagelenderother mortlen extrabor deposit cashdis mrent has_mscharge mscharge discount grant
2 completed 2023-12-08T00:00:00+00:00 2024-01-01T00:00:00+00:00 2023 single log false DLUHC DLUHC billyboy@eyeklaud.com 8 12 2023 Yes - a discounted ownership scheme Right to Acquire (RTA) Yes Yes 2 Flat or maisonette Purpose built 0 Address line 1 Town or city SW1A 1AA 1 E09000003 Barnet Yes Yes 1 30 Non-binary Buyer 1 prefers not to say 17 United Kingdom Full-time - 30 hours or more Yes Partner 35 Non-binary Buyer 2 prefers not to say Buyer prefers not to say Full-time - 30 hours or more Yes 3 Child 14 Non-binary Child under 16 Other Not known Non-binary In government training into work, such as New Deal Prefers not to say Not known Prefers not to say Prefers not to say Local authority tenant No No 1 1 1 1 Don't know Yes Yes No Yes Yes Yes 10000 Yes Yes 10000 Yes Don’t know No Yes No 10 110000.0 Yes 20000.0 Cambridge Building Society 10 Yes 80000.0 Yes 100.0 10000.0

4
spec/fixtures/files/sales_logs_csv_export_labels.csv → spec/fixtures/files/sales_logs_csv_export_labels_24.csv vendored

@ -1,2 +1,2 @@
id,status,duplicate_set_id,created_at,updated_at,old_form_id,collection_start_year,creation_method,is_dpo,owning_organisation_name,managing_organisation_name,created_by,day,month,year,purchid,ownershipsch,type,othtype,companybuy,buylivein,jointpur,jointmore,noint,uprn,uprn_confirmed,address_line1,address_line2,town_or_city,county,pcode1,pcode2,la_known,la,la_label,beds,proptype,builtype,pcodenk,wchair,privacynotice,age1,sex1,ethnic_group,ethnic,national,nationality_all,ecstat1,buy1livein,relat2,age2,sex2,ethnic_group2,ethnicbuy2,nationalbuy2,nationality_all_buyer2,ecstat2,buy2livein,hholdcount,relat3,age3,sex3,ecstat3,relat4,age4,sex4,ecstat4,relat5,age5,sex5,ecstat5,relat6,age6,sex6,ecstat6,prevten,ppcodenk,ppostc1,ppostc2,previous_la_known,prevloc,prevloc_label,pregyrha,pregother,pregla,pregghb,pregblank,buy2living,prevtenbuy2,hhregres,hhregresstill,armedforcesspouse,disabled,wheel,income1nk,income1,inc1mort,income2nk,income2,inc2mort,hb,savingsnk,savings,prevown,prevshared,proplen,staircase,stairbought,stairowned,staircasesale,resale,exday,exmonth,exyear,hoday,homonth,hoyear,lanomagr,soctenant,frombeds,fromprop,socprevten,value,equity,mortgageused,mortgage,mortgagelender,mortgagelenderother,mortlen,extrabor,deposit,cashdis,mrent,has_mscharge,mscharge,discount,grant id,status,duplicate_set_id,created_at,updated_at,old_form_id,collection_start_year,creation_method,is_dpo,owning_organisation_name,managing_organisation_name,created_by,day,month,year,purchid,ownershipsch,type,othtype,companybuy,buylivein,jointpur,jointmore,noint,privacynotice,uprn,uprn_confirmed,address_line1,address_line2,town_or_city,county,pcode1,pcode2,la_known,la,la_label,beds,proptype,builtype,pcodenk,wchair,age1,sex1,ethnic_group,ethnic,national,nationality_all,ecstat1,buy1livein,relat2,age2,sex2,ethnic_group2,ethnicbuy2,nationalbuy2,nationality_all_buyer2,ecstat2,buy2livein,hholdcount,relat3,age3,sex3,ecstat3,relat4,age4,sex4,ecstat4,relat5,age5,sex5,ecstat5,relat6,age6,sex6,ecstat6,prevten,ppcodenk,ppostc1,ppostc2,previous_la_known,prevloc,prevloc_label,pregyrha,pregother,pregla,pregghb,pregblank,buy2living,prevtenbuy2,hhregres,hhregresstill,armedforcesspouse,disabled,wheel,income1nk,income1,inc1mort,income2nk,income2,inc2mort,hb,savingsnk,savings,prevown,prevshared,proplen,staircase,stairbought,stairowned,staircasesale,resale,exday,exmonth,exyear,hoday,homonth,hoyear,lanomagr,soctenant,frombeds,fromprop,socprevten,value,equity,mortgageused,mortgage,mortgagelender,mortgagelenderother,mortlen,extrabor,deposit,cashdis,mrent,has_mscharge,mscharge,discount,grant
,completed,,2023-12-08T00:00:00+00:00,2023-12-08T00:00:00+00:00,,2023,single log,false,DLUHC,DLUHC,billyboy@eyeklaud.com,8,12,2023,,Yes - a discounted ownership scheme,Right to Acquire (RTA),,,,Yes,Yes,Yes,,,Address line 1,,Town or city,,SW1A,1AA,1,E09000003,Barnet,2,Flat or maisonette,Purpose built,0,Yes,1,30,Non-binary,Buyer 1 prefers not to say,17,United Kingdom,,Full-time - 30 hours or more,Yes,Partner,35,Non-binary,Buyer 2 prefers not to say,,Buyer prefers not to say,,Full-time - 30 hours or more,Yes,3,Child,14,Non-binary,Child under 16,Other,Not known,Non-binary,"In government training into work, such as New Deal",Prefers not to say,Not known,Prefers not to say,Prefers not to say,,,,,Local authority tenant,No,,,No,,,1,1,1,1,,Don't know,,Yes,Yes,No,Yes,Yes,Yes,10000,Yes,Yes,10000,Yes,"Don’t know ",No,,Yes,No,10,,,,,,,,,,,,,,,,,110000.0,,Yes,20000.0,Cambridge Building Society,,10,Yes,80000.0,,,Yes,100.0,,10000.0 ,completed,,2023-12-08T00:00:00+00:00,2024-05-01T00:00:00+01:00,,2023,single log,false,DLUHC,DLUHC,billyboy@eyeklaud.com,8,12,2023,,Yes - a discounted ownership scheme,Right to Acquire (RTA),,,,Yes,Yes,Yes,1,,,Address line 1,,Town or city,,SW1A,1AA,1,E09000003,Barnet,2,Flat or maisonette,Purpose built,0,Yes,30,Non-binary,Buyer 1 prefers not to say,17,United Kingdom,,Full-time - 30 hours or more,Yes,Partner,35,Non-binary,Buyer 2 prefers not to say,,Buyer prefers not to say,,Full-time - 30 hours or more,Yes,3,Child,14,Non-binary,Child under 16,Other,Not known,Non-binary,"In government training into work, such as New Deal",Prefers not to say,Not known,Prefers not to say,Prefers not to say,,,,,Local authority tenant,No,,,No,,,1,1,1,1,,Don't know,,Yes,Yes,No,Yes,Yes,Yes,10000,Yes,Yes,10000,Yes,"Don’t know ",No,,Yes,No,10,,,,,,,,,,,,,,,,,110000.0,,Yes,20000.0,Cambridge Building Society,,10,Yes,80000.0,,,Yes,100.0,,10000.0
1 id status duplicate_set_id created_at updated_at old_form_id collection_start_year creation_method is_dpo owning_organisation_name managing_organisation_name created_by day month year purchid ownershipsch type othtype companybuy buylivein jointpur jointmore noint privacynotice uprn uprn_confirmed address_line1 address_line2 town_or_city county pcode1 pcode2 la_known la la_label beds proptype builtype pcodenk wchair age1 sex1 ethnic_group ethnic national nationality_all ecstat1 buy1livein relat2 age2 sex2 ethnic_group2 ethnicbuy2 nationalbuy2 nationality_all_buyer2 ecstat2 buy2livein hholdcount relat3 age3 sex3 ecstat3 relat4 age4 sex4 ecstat4 relat5 age5 sex5 ecstat5 relat6 age6 sex6 ecstat6 prevten ppcodenk ppostc1 ppostc2 previous_la_known prevloc prevloc_label pregyrha pregother pregla pregghb pregblank buy2living prevtenbuy2 hhregres hhregresstill armedforcesspouse disabled wheel income1nk income1 inc1mort income2nk income2 inc2mort hb savingsnk savings prevown prevshared proplen staircase stairbought stairowned staircasesale resale exday exmonth exyear hoday homonth hoyear lanomagr soctenant frombeds fromprop socprevten value equity mortgageused mortgage mortgagelender mortgagelenderother mortlen extrabor deposit cashdis mrent has_mscharge mscharge discount grant
2 completed 2023-12-08T00:00:00+00:00 2024-05-01T00:00:00+01:00 2023 single log false DLUHC DLUHC billyboy@eyeklaud.com 8 12 2023 Yes - a discounted ownership scheme Right to Acquire (RTA) Yes Yes Yes 1 Address line 1 Town or city SW1A 1AA 1 E09000003 Barnet 2 Flat or maisonette Purpose built 0 Yes 30 Non-binary Buyer 1 prefers not to say 17 United Kingdom Full-time - 30 hours or more Yes Partner 35 Non-binary Buyer 2 prefers not to say Buyer prefers not to say Full-time - 30 hours or more Yes 3 Child 14 Non-binary Child under 16 Other Not known Non-binary In government training into work, such as New Deal Prefers not to say Not known Prefers not to say Prefers not to say Local authority tenant No No 1 1 1 1 Don't know Yes Yes No Yes Yes Yes 10000 Yes Yes 10000 Yes Don’t know No Yes No 10 110000.0 Yes 20000.0 Cambridge Building Society 10 Yes 80000.0 Yes 100.0 10000.0

111
spec/lib/tasks/clear_invalidated_earnings_spec.rb

@ -0,0 +1,111 @@
require "rails_helper"
require "rake"
RSpec.describe "clear_invalidated_earnings" do
describe ":clear_invalidated_earnings", type: :task do
subject(:task) { Rake::Task["clear_invalidated_earnings"] }
before do
Rake.application.rake_require("tasks/clear_invalidated_earnings")
Rake::Task.define_task(:environment)
task.reenable
FormHandler.instance.use_real_forms!
end
context "when the rake task is run" do
context "and there are 2023 logs with invalid earnings" do
let(:user) { create(:user) }
let!(:lettings_log) { create(:lettings_log, :completed, created_by: user, voiddate: nil, mrcdate: nil, tenancycode: "123", propcode: "321") }
before do
lettings_log.startdate = Time.zone.local(2023, 4, 4)
lettings_log.incfreq = 1
lettings_log.earnings = 20
lettings_log.hhmemb = 1
lettings_log.ecstat1 = 1
lettings_log.save!(validate: false)
end
it "clears earnings" do
initial_updated_at = lettings_log.updated_at
expect(lettings_log.incfreq).to eq(1)
expect(lettings_log.earnings).to eq(20)
expect(lettings_log.hhmemb).to eq(1)
expect(lettings_log.ecstat1).to eq(1)
expect(Rails.logger).to receive(:info).with("Clearing earnings for lettings log #{lettings_log.id}, owning_organisation_id: #{lettings_log.owning_organisation_id}, managing_organisation_id: #{lettings_log.managing_organisation_id}, startdate: 2023-04-04, tenancy reference: 123, property reference: 321, created_by: #{user.email}(#{user.id})")
task.invoke
lettings_log.reload
expect(lettings_log.incfreq).to eq(nil)
expect(lettings_log.earnings).to eq(nil)
expect(lettings_log.hhmemb).to eq(1)
expect(lettings_log.ecstat1).to eq(1)
expect(lettings_log.updated_at).not_to eq(initial_updated_at)
end
end
context "and there are valid 2023 logs" do
let(:user) { create(:user) }
let!(:lettings_log) { create(:lettings_log, :completed, created_by: user, voiddate: nil, mrcdate: nil) }
before do
lettings_log.startdate = Time.zone.local(2023, 4, 4)
lettings_log.incfreq = 1
lettings_log.earnings = 95
lettings_log.hhmemb = 1
lettings_log.ecstat1 = 1
lettings_log.save!
end
it "does not update the logs" do
initial_updated_at = lettings_log.updated_at
expect(lettings_log.incfreq).to eq(1)
expect(lettings_log.earnings).to eq(95)
expect(lettings_log.hhmemb).to eq(1)
expect(lettings_log.ecstat1).to eq(1)
task.invoke
lettings_log.reload
expect(lettings_log.incfreq).to eq(1)
expect(lettings_log.earnings).to eq(95)
expect(lettings_log.hhmemb).to eq(1)
expect(lettings_log.ecstat1).to eq(1)
expect(lettings_log.updated_at).to eq(initial_updated_at)
end
end
context "and there are 2022 logs" do
let(:user) { create(:user) }
let!(:lettings_log) { create(:lettings_log, :completed, created_by: user, voiddate: nil, mrcdate: nil) }
before do
lettings_log.startdate = Time.zone.local(2022, 4, 4)
lettings_log.incfreq = 1
lettings_log.earnings = 20
lettings_log.hhmemb = 1
lettings_log.ecstat1 = 1
lettings_log.save!(validate: false)
end
it "does not update the logs" do
initial_updated_at = lettings_log.updated_at
expect(lettings_log.incfreq).to eq(1)
expect(lettings_log.earnings).to eq(20)
expect(lettings_log.hhmemb).to eq(1)
expect(lettings_log.ecstat1).to eq(1)
task.invoke
lettings_log.reload
expect(lettings_log.incfreq).to eq(1)
expect(lettings_log.earnings).to eq(20)
expect(lettings_log.hhmemb).to eq(1)
expect(lettings_log.ecstat1).to eq(1)
expect(lettings_log.updated_at).to eq(initial_updated_at)
end
end
end
end
end

81
spec/models/form/lettings/questions/declaration_spec.rb

@ -0,0 +1,81 @@
require "rails_helper"
RSpec.describe Form::Lettings::Questions::Declaration, type: :model do
subject(:question) { described_class.new(question_id, question_definition, page) }
let(:question_id) { nil }
let(:question_definition) { nil }
let(:page) { instance_double(Form::Page) }
let(:subsection) { instance_double(Form::Subsection) }
let(:form) { instance_double(Form) }
before do
allow(form).to receive(:start_year_after_2024?)
allow(page).to receive(:subsection).and_return(subsection)
allow(subsection).to receive(:form).and_return(form)
end
it "has correct page" do
expect(question.page).to eq(page)
end
it "has the correct id" do
expect(question.id).to eq("declaration")
end
it "has the correct header" do
expect(question.header).to eq("Declaration")
end
it "has the correct check_answer_label" do
expect(question.check_answer_label).to eq("Tenant has seen the privacy notice")
end
it "has the correct type" do
expect(question.type).to eq("checkbox")
end
it "is not marked as derived" do
expect(question.derived?).to be false
end
it "has the correct hint" do
expect(question.hint_text).to be_nil
end
context "when the form year is before 2024" do
before do
allow(form).to receive(:start_year_after_2024?).and_return(false)
end
it "has the correct answer_options" do
expect(question.answer_options).to eq({
"declaration" => { "value" => "The tenant has seen the DLUHC privacy notice" },
})
end
it "uses the expected top guidance partial" do
expect(question.top_guidance_partial).to eq("privacy_notice_tenant")
end
end
context "when the form year is >= 2024" do
before do
allow(form).to receive(:start_year_after_2024?).and_return(true)
end
it "has the correct answer_options" do
expect(question.answer_options).to eq({
"declaration" => { "value" => "The tenant has seen or been given access to the DLUHC privacy notice" },
})
end
it "uses the expected top guidance partial" do
expect(question.top_guidance_partial).to eq("privacy_notice_tenant_2024")
end
end
it "returns correct unanswered_error_message" do
expect(question.unanswered_error_message).to eq("You must show the DLUHC privacy notice to the tenant before you can submit this log.")
end
end

74
spec/models/form/lettings/questions/letting_allocation_spec.rb

@ -0,0 +1,74 @@
require "rails_helper"
RSpec.describe Form::Lettings::Questions::LettingAllocation, type: :model do
subject(:question) { described_class.new(question_id, question_definition, page) }
let(:question_id) { nil }
let(:question_definition) { nil }
let(:page) { instance_double(Form::Page) }
let(:subsection) { instance_double(Form::Subsection) }
let(:form) { instance_double(Form) }
before do
allow(form).to receive(:start_year_after_2024?).and_return(false)
allow(page).to receive(:subsection).and_return(subsection)
allow(subsection).to receive(:form).and_return(form)
end
it "has correct page" do
expect(question.page).to eq(page)
end
it "has the correct id" do
expect(question.id).to eq("letting_allocation")
end
it "has the correct header" do
expect(question.header).to eq("How was this letting allocated?")
end
it "has the correct check_answer_label" do
expect(question.check_answer_label).to eq("Allocation system")
end
it "has the correct type" do
expect(question.type).to eq("checkbox")
end
it "is not marked as derived" do
expect(question.derived?).to be false
end
context "with 2023/24 form" do
it "has the correct answer_options" do
expect(question.answer_options).to eq({
"cbl" => { "value" => "Choice-based lettings (CBL)" },
"cap" => { "value" => "Common Allocation Policy (CAP)" },
"chr" => { "value" => "Common housing register (CHR)" },
"divider" => { "value" => true },
"letting_allocation_unknown" => { "value" => "None of these allocation systems" },
})
end
end
context "with 2024/25 form" do
before do
allow(form).to receive(:start_year_after_2024?).and_return(true)
end
it "has the correct answer_options" do
expect(question.answer_options).to eq({
"cbl" => { "value" => "Choice-based lettings (CBL)", "hint" => "Where available vacant properties are advertised and applicants are able to bid for specific properties." },
"cap" => { "value" => "Common Allocation Policy (CAP)", "hint" => "Where a common system agreed between a group of housing providers is used to determine applicant’s priority for housing." },
"chr" => { "value" => "Common housing register (CHR)", "hint" => "Where a single waiting list is used by a group of housing providers to receive and process housing applications. Providers may use different approaches to determine priority." },
"accessible_register" => { "value" => "Accessible housing register", "hint" => "Where the ‘access category’ or another descriptor of whether an available vacant property meets a range of access needs is displayed to applicants during the allocations process." },
"divider" => { "value" => true },
"letting_allocation_unknown" => { "value" => "None of these allocation systems" },
})
end
end
it "has the correct check_answers_card_number" do
expect(question.check_answers_card_number).to eq(0)
end
end

2
spec/models/form/lettings/questions/nationality_all_group_spec.rb

@ -26,7 +26,7 @@ RSpec.describe Form::Lettings::Questions::NationalityAllGroup, type: :model do
end end
it "has the correct hint_text" do it "has the correct hint_text" do
expect(question.hint_text).to eq("The lead tenant is the person in the household who does the most paid work. If several people do the same paid work, the lead tenant is whoever is the oldest.") expect(question.hint_text).to eq("The lead tenant is the person in the household who does the most paid work. If several people do the same paid work, the lead tenant is whoever is the oldest. If the lead tenant is a dual national of the United Kingdom and another country, enter United Kingdom. If they are a dual national of two other countries, the tenant should decide which country to enter.")
end end
it "has the correct answer_options" do it "has the correct answer_options" do

417
spec/models/form/lettings/subsections/household_characteristics_spec.rb

@ -6,144 +6,295 @@ RSpec.describe Form::Lettings::Subsections::HouseholdCharacteristics, type: :mod
let(:subsection_id) { nil } let(:subsection_id) { nil }
let(:subsection_definition) { nil } let(:subsection_definition) { nil }
let(:section) { instance_double(Form::Lettings::Sections::Household) } let(:section) { instance_double(Form::Lettings::Sections::Household) }
let(:form) { instance_double(Form) }
before do
allow(section).to receive(:form).and_return(form)
end
it "has correct section" do it "has correct section" do
expect(household_characteristics.section).to eq(section) expect(household_characteristics.section).to eq(section)
end end
it "has correct pages" do context "with start year before 2024" do
expect(household_characteristics.pages.map(&:id)).to eq( before do
%w[ allow(form).to receive(:start_year_after_2024?).and_return(false)
declaration end
household_members
no_females_pregnant_household_lead_hhmemb_value_check it "has correct pages" do
females_in_soft_age_range_in_pregnant_household_lead_hhmemb_value_check expect(household_characteristics.pages.map(&:id)).to eq(
lead_tenant_age %w[
no_females_pregnant_household_lead_age_value_check declaration
females_in_soft_age_range_in_pregnant_household_lead_age_value_check household_members
age_lead_tenant_under_retirement_value_check no_females_pregnant_household_lead_hhmemb_value_check
age_lead_tenant_over_retirement_value_check females_in_soft_age_range_in_pregnant_household_lead_hhmemb_value_check
lead_tenant_gender_identity lead_tenant_age
no_females_pregnant_household_lead_value_check no_females_pregnant_household_lead_age_value_check
females_in_soft_age_range_in_pregnant_household_lead_value_check females_in_soft_age_range_in_pregnant_household_lead_age_value_check
gender_lead_tenant_over_retirement_value_check age_lead_tenant_under_retirement_value_check
lead_tenant_ethnic_group age_lead_tenant_over_retirement_value_check
lead_tenant_ethnic_background_arab lead_tenant_gender_identity
lead_tenant_ethnic_background_asian no_females_pregnant_household_lead_value_check
lead_tenant_ethnic_background_black females_in_soft_age_range_in_pregnant_household_lead_value_check
lead_tenant_ethnic_background_mixed gender_lead_tenant_over_retirement_value_check
lead_tenant_ethnic_background_white lead_tenant_ethnic_group
lead_tenant_nationality lead_tenant_ethnic_background_arab
lead_tenant_working_situation lead_tenant_ethnic_background_asian
working_situation_lead_tenant_under_retirement_value_check lead_tenant_ethnic_background_black
working_situation_lead_tenant_over_retirement_value_check lead_tenant_ethnic_background_mixed
person_2_known lead_tenant_ethnic_background_white
person_2_relationship_to_lead lead_tenant_nationality
person_2_age_child lead_tenant_working_situation
person_2_age_non_child working_situation_lead_tenant_under_retirement_value_check
no_females_pregnant_household_person_2_age_value_check working_situation_lead_tenant_over_retirement_value_check
females_in_soft_age_range_in_pregnant_household_person_2_age_value_check person_2_known
age_2_under_retirement_value_check person_2_relationship_to_lead
age_2_over_retirement_value_check person_2_age_child
person_2_gender_identity person_2_age_non_child
no_females_pregnant_household_person_2_value_check no_females_pregnant_household_person_2_age_value_check
females_in_soft_age_range_in_pregnant_household_person_2_value_check females_in_soft_age_range_in_pregnant_household_person_2_age_value_check
gender_2_over_retirement_value_check age_2_under_retirement_value_check
person_2_working_situation age_2_over_retirement_value_check
working_situation_2_under_retirement_value_check person_2_gender_identity
working_situation_2_over_retirement_value_check no_females_pregnant_household_person_2_value_check
person_3_known females_in_soft_age_range_in_pregnant_household_person_2_value_check
person_3_relationship_to_lead gender_2_over_retirement_value_check
person_3_age_child person_2_working_situation
person_3_age_non_child working_situation_2_under_retirement_value_check
no_females_pregnant_household_person_3_age_value_check working_situation_2_over_retirement_value_check
females_in_soft_age_range_in_pregnant_household_person_3_age_value_check person_3_known
age_3_under_retirement_value_check person_3_relationship_to_lead
age_3_over_retirement_value_check person_3_age_child
person_3_gender_identity person_3_age_non_child
no_females_pregnant_household_person_3_value_check no_females_pregnant_household_person_3_age_value_check
females_in_soft_age_range_in_pregnant_household_person_3_value_check females_in_soft_age_range_in_pregnant_household_person_3_age_value_check
gender_3_over_retirement_value_check age_3_under_retirement_value_check
person_3_working_situation age_3_over_retirement_value_check
working_situation_3_under_retirement_value_check person_3_gender_identity
working_situation_3_over_retirement_value_check no_females_pregnant_household_person_3_value_check
person_4_known females_in_soft_age_range_in_pregnant_household_person_3_value_check
person_4_relationship_to_lead gender_3_over_retirement_value_check
person_4_age_child person_3_working_situation
person_4_age_non_child working_situation_3_under_retirement_value_check
no_females_pregnant_household_person_4_age_value_check working_situation_3_over_retirement_value_check
females_in_soft_age_range_in_pregnant_household_person_4_age_value_check person_4_known
age_4_under_retirement_value_check person_4_relationship_to_lead
age_4_over_retirement_value_check person_4_age_child
person_4_gender_identity person_4_age_non_child
no_females_pregnant_household_person_4_value_check no_females_pregnant_household_person_4_age_value_check
females_in_soft_age_range_in_pregnant_household_person_4_value_check females_in_soft_age_range_in_pregnant_household_person_4_age_value_check
gender_4_over_retirement_value_check age_4_under_retirement_value_check
person_4_working_situation age_4_over_retirement_value_check
working_situation_4_under_retirement_value_check person_4_gender_identity
working_situation_4_over_retirement_value_check no_females_pregnant_household_person_4_value_check
person_5_known females_in_soft_age_range_in_pregnant_household_person_4_value_check
person_5_relationship_to_lead gender_4_over_retirement_value_check
person_5_age_child person_4_working_situation
person_5_age_non_child working_situation_4_under_retirement_value_check
no_females_pregnant_household_person_5_age_value_check working_situation_4_over_retirement_value_check
females_in_soft_age_range_in_pregnant_household_person_5_age_value_check person_5_known
age_5_under_retirement_value_check person_5_relationship_to_lead
age_5_over_retirement_value_check person_5_age_child
person_5_gender_identity person_5_age_non_child
no_females_pregnant_household_person_5_value_check no_females_pregnant_household_person_5_age_value_check
females_in_soft_age_range_in_pregnant_household_person_5_value_check females_in_soft_age_range_in_pregnant_household_person_5_age_value_check
gender_5_over_retirement_value_check age_5_under_retirement_value_check
person_5_working_situation age_5_over_retirement_value_check
working_situation_5_under_retirement_value_check person_5_gender_identity
working_situation_5_over_retirement_value_check no_females_pregnant_household_person_5_value_check
person_6_known females_in_soft_age_range_in_pregnant_household_person_5_value_check
person_6_relationship_to_lead gender_5_over_retirement_value_check
person_6_age_child person_5_working_situation
person_6_age_non_child working_situation_5_under_retirement_value_check
no_females_pregnant_household_person_6_age_value_check working_situation_5_over_retirement_value_check
females_in_soft_age_range_in_pregnant_household_person_6_age_value_check person_6_known
age_6_under_retirement_value_check person_6_relationship_to_lead
age_6_over_retirement_value_check person_6_age_child
person_6_gender_identity person_6_age_non_child
no_females_pregnant_household_person_6_value_check no_females_pregnant_household_person_6_age_value_check
females_in_soft_age_range_in_pregnant_household_person_6_value_check females_in_soft_age_range_in_pregnant_household_person_6_age_value_check
gender_6_over_retirement_value_check age_6_under_retirement_value_check
person_6_working_situation age_6_over_retirement_value_check
working_situation_6_under_retirement_value_check person_6_gender_identity
working_situation_6_over_retirement_value_check no_females_pregnant_household_person_6_value_check
person_7_known females_in_soft_age_range_in_pregnant_household_person_6_value_check
person_7_relationship_to_lead gender_6_over_retirement_value_check
person_7_age_child person_6_working_situation
person_7_age_non_child working_situation_6_under_retirement_value_check
no_females_pregnant_household_person_7_age_value_check working_situation_6_over_retirement_value_check
females_in_soft_age_range_in_pregnant_household_person_7_age_value_check person_7_known
age_7_under_retirement_value_check person_7_relationship_to_lead
age_7_over_retirement_value_check person_7_age_child
person_7_gender_identity person_7_age_non_child
no_females_pregnant_household_person_7_value_check no_females_pregnant_household_person_7_age_value_check
females_in_soft_age_range_in_pregnant_household_person_7_value_check females_in_soft_age_range_in_pregnant_household_person_7_age_value_check
gender_7_over_retirement_value_check age_7_under_retirement_value_check
person_7_working_situation age_7_over_retirement_value_check
working_situation_7_under_retirement_value_check person_7_gender_identity
working_situation_7_over_retirement_value_check no_females_pregnant_household_person_7_value_check
person_8_known females_in_soft_age_range_in_pregnant_household_person_7_value_check
person_8_relationship_to_lead gender_7_over_retirement_value_check
person_8_age_child person_7_working_situation
person_8_age_non_child working_situation_7_under_retirement_value_check
no_females_pregnant_household_person_8_age_value_check working_situation_7_over_retirement_value_check
females_in_soft_age_range_in_pregnant_household_person_8_age_value_check person_8_known
age_8_under_retirement_value_check person_8_relationship_to_lead
age_8_over_retirement_value_check person_8_age_child
person_8_gender_identity person_8_age_non_child
no_females_pregnant_household_person_8_value_check no_females_pregnant_household_person_8_age_value_check
females_in_soft_age_range_in_pregnant_household_person_8_value_check females_in_soft_age_range_in_pregnant_household_person_8_age_value_check
gender_8_over_retirement_value_check age_8_under_retirement_value_check
person_8_working_situation age_8_over_retirement_value_check
working_situation_8_under_retirement_value_check person_8_gender_identity
working_situation_8_over_retirement_value_check no_females_pregnant_household_person_8_value_check
], females_in_soft_age_range_in_pregnant_household_person_8_value_check
) gender_8_over_retirement_value_check
person_8_working_situation
working_situation_8_under_retirement_value_check
working_situation_8_over_retirement_value_check
],
)
end
end
context "with start year >= 2024" do
before do
allow(form).to receive(:start_year_after_2024?).and_return(true)
end
it "has correct pages" do
expect(household_characteristics.pages.map(&:id)).to eq(
%w[
household_members
no_females_pregnant_household_lead_hhmemb_value_check
females_in_soft_age_range_in_pregnant_household_lead_hhmemb_value_check
lead_tenant_age
no_females_pregnant_household_lead_age_value_check
females_in_soft_age_range_in_pregnant_household_lead_age_value_check
age_lead_tenant_under_retirement_value_check
age_lead_tenant_over_retirement_value_check
lead_tenant_gender_identity
no_females_pregnant_household_lead_value_check
females_in_soft_age_range_in_pregnant_household_lead_value_check
gender_lead_tenant_over_retirement_value_check
lead_tenant_ethnic_group
lead_tenant_ethnic_background_arab
lead_tenant_ethnic_background_asian
lead_tenant_ethnic_background_black
lead_tenant_ethnic_background_mixed
lead_tenant_ethnic_background_white
lead_tenant_nationality
lead_tenant_working_situation
working_situation_lead_tenant_under_retirement_value_check
working_situation_lead_tenant_over_retirement_value_check
person_2_known
person_2_relationship_to_lead
person_2_age_child
person_2_age_non_child
no_females_pregnant_household_person_2_age_value_check
females_in_soft_age_range_in_pregnant_household_person_2_age_value_check
age_2_under_retirement_value_check
age_2_over_retirement_value_check
person_2_gender_identity
no_females_pregnant_household_person_2_value_check
females_in_soft_age_range_in_pregnant_household_person_2_value_check
gender_2_over_retirement_value_check
person_2_working_situation
working_situation_2_under_retirement_value_check
working_situation_2_over_retirement_value_check
person_3_known
person_3_relationship_to_lead
person_3_age_child
person_3_age_non_child
no_females_pregnant_household_person_3_age_value_check
females_in_soft_age_range_in_pregnant_household_person_3_age_value_check
age_3_under_retirement_value_check
age_3_over_retirement_value_check
person_3_gender_identity
no_females_pregnant_household_person_3_value_check
females_in_soft_age_range_in_pregnant_household_person_3_value_check
gender_3_over_retirement_value_check
person_3_working_situation
working_situation_3_under_retirement_value_check
working_situation_3_over_retirement_value_check
person_4_known
person_4_relationship_to_lead
person_4_age_child
person_4_age_non_child
no_females_pregnant_household_person_4_age_value_check
females_in_soft_age_range_in_pregnant_household_person_4_age_value_check
age_4_under_retirement_value_check
age_4_over_retirement_value_check
person_4_gender_identity
no_females_pregnant_household_person_4_value_check
females_in_soft_age_range_in_pregnant_household_person_4_value_check
gender_4_over_retirement_value_check
person_4_working_situation
working_situation_4_under_retirement_value_check
working_situation_4_over_retirement_value_check
person_5_known
person_5_relationship_to_lead
person_5_age_child
person_5_age_non_child
no_females_pregnant_household_person_5_age_value_check
females_in_soft_age_range_in_pregnant_household_person_5_age_value_check
age_5_under_retirement_value_check
age_5_over_retirement_value_check
person_5_gender_identity
no_females_pregnant_household_person_5_value_check
females_in_soft_age_range_in_pregnant_household_person_5_value_check
gender_5_over_retirement_value_check
person_5_working_situation
working_situation_5_under_retirement_value_check
working_situation_5_over_retirement_value_check
person_6_known
person_6_relationship_to_lead
person_6_age_child
person_6_age_non_child
no_females_pregnant_household_person_6_age_value_check
females_in_soft_age_range_in_pregnant_household_person_6_age_value_check
age_6_under_retirement_value_check
age_6_over_retirement_value_check
person_6_gender_identity
no_females_pregnant_household_person_6_value_check
females_in_soft_age_range_in_pregnant_household_person_6_value_check
gender_6_over_retirement_value_check
person_6_working_situation
working_situation_6_under_retirement_value_check
working_situation_6_over_retirement_value_check
person_7_known
person_7_relationship_to_lead
person_7_age_child
person_7_age_non_child
no_females_pregnant_household_person_7_age_value_check
females_in_soft_age_range_in_pregnant_household_person_7_age_value_check
age_7_under_retirement_value_check
age_7_over_retirement_value_check
person_7_gender_identity
no_females_pregnant_household_person_7_value_check
females_in_soft_age_range_in_pregnant_household_person_7_value_check
gender_7_over_retirement_value_check
person_7_working_situation
working_situation_7_under_retirement_value_check
working_situation_7_over_retirement_value_check
person_8_known
person_8_relationship_to_lead
person_8_age_child
person_8_age_non_child
no_females_pregnant_household_person_8_age_value_check
females_in_soft_age_range_in_pregnant_household_person_8_age_value_check
age_8_under_retirement_value_check
age_8_over_retirement_value_check
person_8_gender_identity
no_females_pregnant_household_person_8_value_check
females_in_soft_age_range_in_pregnant_household_person_8_value_check
gender_8_over_retirement_value_check
person_8_working_situation
working_situation_8_under_retirement_value_check
working_situation_8_over_retirement_value_check
],
)
end
end end
it "has the correct id" do it "has the correct id" do

62
spec/models/form/lettings/subsections/setup_spec.rb

@ -6,38 +6,45 @@ RSpec.describe Form::Lettings::Subsections::Setup, type: :model do
let(:subsection_id) { nil } let(:subsection_id) { nil }
let(:subsection_definition) { nil } let(:subsection_definition) { nil }
let(:section) { instance_double(Form::Lettings::Sections::Setup) } let(:section) { instance_double(Form::Lettings::Sections::Setup) }
let(:form) { instance_double(Form) }
before do
allow(section).to receive(:form).and_return(form)
end
it "has correct section" do it "has correct section" do
expect(setup.section).to eq(section) expect(setup.section).to eq(section)
end end
it "has correct pages" do context "with start year before 2024" do
expect(setup.pages.map(&:id)).to eq( before do
%w[ allow(form).to receive(:start_year_after_2024?).and_return(false)
stock_owner end
managing_organisation
created_by
needs_type
scheme
location
renewal
tenancy_start_date
rent_type
tenant_code
property_reference
],
)
end
it "has the correct id" do it "has correct pages" do
expect(setup.id).to eq("setup") expect(setup.pages.map(&:id)).to eq(
%w[
stock_owner
managing_organisation
created_by
needs_type
scheme
location
renewal
tenancy_start_date
rent_type
tenant_code
property_reference
],
)
end
end end
it "has the correct label" do context "with start year >= 2024" do
expect(setup.label).to eq("Set up this lettings log") before do
end allow(form).to receive(:start_year_after_2024?).and_return(true)
end
context "when not production" do
it "has correct pages" do it "has correct pages" do
expect(setup.pages.map(&:id)).to eq( expect(setup.pages.map(&:id)).to eq(
%w[ %w[
@ -52,8 +59,17 @@ RSpec.describe Form::Lettings::Subsections::Setup, type: :model do
rent_type rent_type
tenant_code tenant_code
property_reference property_reference
declaration
], ],
) )
end end
end end
it "has the correct id" do
expect(setup.id).to eq("setup")
end
it "has the correct label" do
expect(setup.label).to eq("Set up this lettings log")
end
end end

40
spec/models/form/sales/pages/about_deposit_with_discount_spec.rb

@ -1,12 +1,16 @@
require "rails_helper" require "rails_helper"
RSpec.describe Form::Sales::Pages::AboutDepositWithDiscount, type: :model do RSpec.describe Form::Sales::Pages::AboutDepositWithDiscount, type: :model do
subject(:page) { described_class.new(page_id, page_definition, subsection) } subject(:page) { described_class.new(page_id, page_definition, subsection, optional: false) }
let(:page_id) { nil } let(:page_id) { "about_deposit_with_discount" }
let(:page_definition) { nil } let(:page_definition) { nil }
let(:subsection) { instance_double(Form::Subsection) } let(:subsection) { instance_double(Form::Subsection) }
before do
allow(subsection).to receive(:form).and_return(instance_double(Form, start_year_after_2024?: false))
end
it "has correct subsection" do it "has correct subsection" do
expect(page.subsection).to eq(subsection) expect(page.subsection).to eq(subsection)
end end
@ -32,4 +36,36 @@ RSpec.describe Form::Sales::Pages::AboutDepositWithDiscount, type: :model do
[{ "is_type_discount?" => true }], [{ "is_type_discount?" => true }],
) )
end end
context "when optional" do
subject(:page) { described_class.new(page_id, page_definition, subsection, optional: true) }
it "has correct depends_on" do
expect(page.depends_on).to eq(
[{ "is_type_discount?" => true }],
)
end
end
context "when it's a 2024 form" do
before do
allow(subsection).to receive(:form).and_return(instance_double(Form, start_year_after_2024?: true))
end
it "has correct depends_on" do
expect(page.depends_on).to eq(
[{ "is_type_discount?" => true, "stairowned_100?" => false }],
)
end
context "and optional" do
subject(:page) { described_class.new(page_id, page_definition, subsection, optional: true) }
it "has correct depends_on" do
expect(page.depends_on).to eq(
[{ "is_type_discount?" => true, "stairowned_100?" => true }],
)
end
end
end
end end

44
spec/models/form/sales/pages/about_deposit_without_discount_spec.rb

@ -1,12 +1,16 @@
require "rails_helper" require "rails_helper"
RSpec.describe Form::Sales::Pages::AboutDepositWithoutDiscount, type: :model do RSpec.describe Form::Sales::Pages::AboutDepositWithoutDiscount, type: :model do
subject(:page) { described_class.new(page_id, page_definition, subsection, ownershipsch: 1) } subject(:page) { described_class.new(page_id, page_definition, subsection, ownershipsch: 1, optional: false) }
let(:page_id) { nil } let(:page_id) { nil }
let(:page_definition) { nil } let(:page_definition) { nil }
let(:subsection) { instance_double(Form::Subsection) } let(:subsection) { instance_double(Form::Subsection) }
before do
allow(subsection).to receive(:form).and_return(instance_double(Form, start_year_after_2024?: false))
end
it "has correct subsection" do it "has correct subsection" do
expect(page.subsection).to eq(subsection) expect(page.subsection).to eq(subsection)
end end
@ -34,4 +38,42 @@ RSpec.describe Form::Sales::Pages::AboutDepositWithoutDiscount, type: :model do
{ "ownershipsch" => 3, "mortgageused" => 1 }], { "ownershipsch" => 3, "mortgageused" => 1 }],
) )
end end
context "when optional is true" do
subject(:page) { described_class.new(page_id, page_definition, subsection, ownershipsch: 1, optional: true) }
it "has correct depends_on" do
expect(page.depends_on).to eq(
[{ "is_type_discount?" => false, "ownershipsch" => 1 },
{ "ownershipsch" => 2 },
{ "ownershipsch" => 3, "mortgageused" => 1 }],
)
end
end
context "when it's a 2024 form" do
before do
allow(subsection).to receive(:form).and_return(instance_double(Form, start_year_after_2024?: true))
end
it "has correct depends_on" do
expect(page.depends_on).to eq(
[{ "is_type_discount?" => false, "ownershipsch" => 1, "stairowned_100?" => false },
{ "ownershipsch" => 2 },
{ "ownershipsch" => 3, "mortgageused" => 1 }],
)
end
context "and optional is true" do
subject(:page) { described_class.new(page_id, page_definition, subsection, ownershipsch: 1, optional: true) }
it "has correct depends_on" do
expect(page.depends_on).to eq(
[{ "is_type_discount?" => false, "ownershipsch" => 1, "stairowned_100?" => true },
{ "ownershipsch" => 2 },
{ "ownershipsch" => 3, "mortgageused" => 1 }],
)
end
end
end
end end

35
spec/models/form/sales/pages/last_accommodation_la_spec.rb

@ -5,8 +5,22 @@ RSpec.describe Form::Sales::Pages::LastAccommodationLa, type: :model do
let(:page_id) { nil } let(:page_id) { nil }
let(:page_definition) { nil } let(:page_definition) { nil }
let(:subsection) { instance_double(Form::Subsection, form: instance_double(Form, start_date:)) } let(:subsection) { instance_double(Form::Subsection, form: instance_double(Form, depends_on_met: true)) }
let(:start_date) { Time.utc(2022, 4, 1) } let(:start_date) { Time.utc(2022, 4, 1) }
let(:log) { create(:sales_log, :completed, saledate: now) }
let(:now) { Time.zone.local(2023, 4, 4) }
before do
Timecop.freeze(now)
Singleton.__init__(FormHandler)
allow(subsection).to receive(:depends_on).and_return(nil)
allow(subsection).to receive(:enabled?).and_return(true)
end
after do
Timecop.return
Singleton.__init__(FormHandler)
end
it "has correct subsection" do it "has correct subsection" do
expect(page.subsection).to eq(subsection) expect(page.subsection).to eq(subsection)
@ -33,4 +47,23 @@ RSpec.describe Form::Sales::Pages::LastAccommodationLa, type: :model do
"is_previous_la_inferred" => false, "is_previous_la_inferred" => false,
}]) }])
end end
it "is routed to" do
log.ownershipsch = 2
expect(page).to be_routed_to(log, nil)
end
context "with 2024 form" do
let(:now) { Time.zone.local(2024, 4, 4) }
it "is routed to for 2024 non discounted sale logs" do
log.update!(ownershipsch: 1)
expect(page).to be_routed_to(log, nil)
end
it "is not routed to for 2024 discounted sale logs" do
log.update!(ownershipsch: 2)
expect(page).not_to be_routed_to(log, nil)
end
end
end end

33
spec/models/form/sales/pages/last_accommodation_spec.rb

@ -3,10 +3,24 @@ require "rails_helper"
RSpec.describe Form::Sales::Pages::LastAccommodation, type: :model do RSpec.describe Form::Sales::Pages::LastAccommodation, type: :model do
subject(:page) { described_class.new(page_id, page_definition, subsection) } subject(:page) { described_class.new(page_id, page_definition, subsection) }
let(:log) { create(:sales_log, :completed, saledate: now) }
let(:now) { Time.zone.local(2023, 4, 4) }
let(:page_id) { nil } let(:page_id) { nil }
let(:page_definition) { nil } let(:page_definition) { nil }
let(:subsection) { instance_double(Form::Subsection) } let(:subsection) { instance_double(Form::Subsection) }
before do
Timecop.freeze(now)
Singleton.__init__(FormHandler)
allow(subsection).to receive(:depends_on).and_return(nil)
end
after do
Timecop.return
Singleton.__init__(FormHandler)
end
it "has correct subsection" do it "has correct subsection" do
expect(page.subsection).to eq(subsection) expect(page.subsection).to eq(subsection)
end end
@ -30,4 +44,23 @@ RSpec.describe Form::Sales::Pages::LastAccommodation, type: :model do
it "has correct depends_on" do it "has correct depends_on" do
expect(page.depends_on).to be_nil expect(page.depends_on).to be_nil
end end
it "is routed to" do
log.ownershipsch = 2
expect(page).to be_routed_to(log, nil)
end
context "with 2024 form" do
let(:now) { Time.zone.local(2024, 4, 4) }
it "is routed to for 2024 non discounted sale logs" do
log.update!(ownershipsch: 1)
expect(page).to be_routed_to(log, nil)
end
it "is not routed to for 2024 discounted sale logs" do
log.update!(ownershipsch: 2)
expect(page).not_to be_routed_to(log, nil)
end
end
end end

6
spec/models/form/sales/pages/privacy_notice_spec.rb

@ -6,6 +6,12 @@ RSpec.describe Form::Sales::Pages::PrivacyNotice, type: :model do
let(:page_id) { nil } let(:page_id) { nil }
let(:page_definition) { nil } let(:page_definition) { nil }
let(:subsection) { instance_double(Form::Subsection) } let(:subsection) { instance_double(Form::Subsection) }
let(:form) { instance_double(Form) }
before do
allow(subsection).to receive(:form).and_return(form)
allow(form).to receive(:start_year_after_2024?)
end
it "has correct subsection" do it "has correct subsection" do
expect(page.subsection).to eq(subsection) expect(page.subsection).to eq(subsection)

10
spec/models/form/sales/questions/deposit_amount_spec.rb

@ -1,7 +1,7 @@
require "rails_helper" require "rails_helper"
RSpec.describe Form::Sales::Questions::DepositAmount, type: :model do RSpec.describe Form::Sales::Questions::DepositAmount, type: :model do
subject(:question) { described_class.new(question_id, question_definition, page, ownershipsch: 1) } subject(:question) { described_class.new(question_id, question_definition, page, ownershipsch: 1, optional: false) }
let(:question_id) { nil } let(:question_id) { nil }
let(:question_definition) { nil } let(:question_definition) { nil }
@ -50,4 +50,12 @@ RSpec.describe Form::Sales::Questions::DepositAmount, type: :model do
it "has correct max" do it "has correct max" do
expect(question.max).to eq(999_999) expect(question.max).to eq(999_999)
end end
context "when optional iis true" do
subject(:question) { described_class.new(question_id, question_definition, page, ownershipsch: 1, optional: true) }
it "has a correct hint_text" do
expect(question.hint_text).to eq("Enter the total cash sum paid by the buyer towards the property that was not funded by the mortgage. As this is a fully staircased sale this question is optional. If you do not have the information available click save and continue")
end
end
end end

293
spec/models/form/sales/questions/mortgage_lender_spec.rb

@ -6,6 +6,14 @@ RSpec.describe Form::Sales::Questions::MortgageLender, type: :model do
let(:question_id) { nil } let(:question_id) { nil }
let(:question_definition) { nil } let(:question_definition) { nil }
let(:page) { instance_double(Form::Page) } let(:page) { instance_double(Form::Page) }
let(:subsection) { instance_double(Form::Subsection) }
let(:form) { instance_double(Form) }
before do
allow(form).to receive(:start_year_after_2024?)
allow(page).to receive(:subsection).and_return(subsection)
allow(subsection).to receive(:form).and_return(form)
end
it "has correct page" do it "has correct page" do
expect(question.page).to eq(page) expect(question.page).to eq(page)
@ -44,96 +52,203 @@ RSpec.describe Form::Sales::Questions::MortgageLender, type: :model do
expect(question.top_guidance_partial).to be_nil expect(question.top_guidance_partial).to be_nil
end end
it "has the correct answer_options" do context "when form year is before 2024" do
expect(question.answer_options).to eq({ before do
"" => "Select an option", allow(form).to receive(:start_year_after_2024?).and_return(false)
"0" => "Don’t know", end
"1" => "Atom Bank",
"2" => "Barclays Bank PLC", it "has the correct answer_options" do
"3" => "Bath Building Society", expect(question.answer_options).to eq({
"4" => "Buckinghamshire Building Society", "" => "Select an option",
"5" => "Cambridge Building Society", "0" => "Don’t know",
"6" => "Coventry Building Society", "1" => "Atom Bank",
"7" => "Cumberland Building Society", "2" => "Barclays Bank PLC",
"8" => "Darlington Building Society", "3" => "Bath Building Society",
"9" => "Dudley Building Society", "4" => "Buckinghamshire Building Society",
"10" => "Ecology Building Society", "5" => "Cambridge Building Society",
"11" => "Halifax", "6" => "Coventry Building Society",
"12" => "Hanley Economic Building Society", "7" => "Cumberland Building Society",
"13" => "Hinckley and Rugby Building Society", "8" => "Darlington Building Society",
"14" => "Holmesdale Building Society", "9" => "Dudley Building Society",
"15" => "Ipswich Building Society", "10" => "Ecology Building Society",
"16" => "Leeds Building Society", "11" => "Halifax",
"17" => "Lloyds Bank", "12" => "Hanley Economic Building Society",
"18" => "Mansfield Building Society", "13" => "Hinckley and Rugby Building Society",
"19" => "Market Harborough Building Society", "14" => "Holmesdale Building Society",
"20" => "Melton Mowbray Building Society", "15" => "Ipswich Building Society",
"21" => "Nationwide Building Society", "16" => "Leeds Building Society",
"22" => "Natwest", "17" => "Lloyds Bank",
"23" => "Nedbank Private Wealth", "18" => "Mansfield Building Society",
"24" => "Newbury Building Society", "19" => "Market Harborough Building Society",
"25" => "OneSavings Bank", "20" => "Melton Mowbray Building Society",
"26" => "Parity Trust", "21" => "Nationwide Building Society",
"27" => "Penrith Building Society", "22" => "Natwest",
"28" => "Pepper Homeloans", "23" => "Nedbank Private Wealth",
"29" => "Royal Bank of Scotland", "24" => "Newbury Building Society",
"30" => "Santander", "25" => "OneSavings Bank",
"31" => "Skipton Building Society", "26" => "Parity Trust",
"32" => "Teachers Building Society", "27" => "Penrith Building Society",
"33" => "The Co-operative Bank", "28" => "Pepper Homeloans",
"34" => "Tipton & Coseley Building Society", "29" => "Royal Bank of Scotland",
"35" => "TSB", "30" => "Santander",
"36" => "Ulster Bank", "31" => "Skipton Building Society",
"37" => "Virgin Money", "32" => "Teachers Building Society",
"38" => "West Bromwich Building Society", "33" => "The Co-operative Bank",
"39" => "Yorkshire Building Society", "34" => "Tipton & Coseley Building Society",
"40" => "Other", "35" => "TSB",
}) "36" => "Ulster Bank",
"37" => "Virgin Money",
"38" => "West Bromwich Building Society",
"39" => "Yorkshire Building Society",
"40" => "Other",
})
end
it "has the correct displayed_answer_options" do
expect(question.displayed_answer_options(nil, nil)).to eq({
"" => "Select an option",
"1" => "Atom Bank",
"2" => "Barclays Bank PLC",
"3" => "Bath Building Society",
"4" => "Buckinghamshire Building Society",
"5" => "Cambridge Building Society",
"6" => "Coventry Building Society",
"7" => "Cumberland Building Society",
"8" => "Darlington Building Society",
"9" => "Dudley Building Society",
"10" => "Ecology Building Society",
"11" => "Halifax",
"12" => "Hanley Economic Building Society",
"13" => "Hinckley and Rugby Building Society",
"14" => "Holmesdale Building Society",
"15" => "Ipswich Building Society",
"16" => "Leeds Building Society",
"17" => "Lloyds Bank",
"18" => "Mansfield Building Society",
"19" => "Market Harborough Building Society",
"20" => "Melton Mowbray Building Society",
"21" => "Nationwide Building Society",
"22" => "Natwest",
"23" => "Nedbank Private Wealth",
"24" => "Newbury Building Society",
"25" => "OneSavings Bank",
"26" => "Parity Trust",
"27" => "Penrith Building Society",
"28" => "Pepper Homeloans",
"29" => "Royal Bank of Scotland",
"30" => "Santander",
"31" => "Skipton Building Society",
"32" => "Teachers Building Society",
"33" => "The Co-operative Bank",
"34" => "Tipton & Coseley Building Society",
"35" => "TSB",
"36" => "Ulster Bank",
"37" => "Virgin Money",
"38" => "West Bromwich Building Society",
"39" => "Yorkshire Building Society",
"40" => "Other",
})
end
end end
it "has the correct displayed_answer_options" do context "when form year is >= 2024" do
expect(question.displayed_answer_options(nil, nil)).to eq({ before do
"" => "Select an option", allow(form).to receive(:start_year_after_2024?).and_return(true)
"1" => "Atom Bank", end
"2" => "Barclays Bank PLC",
"3" => "Bath Building Society", it "has the correct answer_options" do
"4" => "Buckinghamshire Building Society", expect(question.answer_options).to eq({
"5" => "Cambridge Building Society", "" => "Select an option",
"6" => "Coventry Building Society", "0" => "Don’t know",
"7" => "Cumberland Building Society", "1" => "Atom Bank",
"8" => "Darlington Building Society", "2" => "Barclays Bank PLC",
"9" => "Dudley Building Society", "3" => "Bath Building Society",
"10" => "Ecology Building Society", "4" => "Buckinghamshire Building Society",
"11" => "Halifax", "5" => "Cambridge Building Society",
"12" => "Hanley Economic Building Society", "6" => "Coventry Building Society",
"13" => "Hinckley and Rugby Building Society", "7" => "Cumberland Building Society",
"14" => "Holmesdale Building Society", "8" => "Darlington Building Society",
"15" => "Ipswich Building Society", "9" => "Dudley Building Society",
"16" => "Leeds Building Society", "10" => "Ecology Building Society",
"17" => "Lloyds Bank", "11" => "Halifax",
"18" => "Mansfield Building Society", "12" => "Hanley Economic Building Society",
"19" => "Market Harborough Building Society", "13" => "Hinckley and Rugby Building Society",
"20" => "Melton Mowbray Building Society", "14" => "Holmesdale Building Society",
"21" => "Nationwide Building Society", "15" => "Ipswich Building Society",
"22" => "Natwest", "16" => "Leeds Building Society",
"23" => "Nedbank Private Wealth", "17" => "Lloyds Bank",
"24" => "Newbury Building Society", "18" => "Mansfield Building Society",
"25" => "OneSavings Bank", "19" => "Market Harborough Building Society",
"26" => "Parity Trust", "20" => "Melton Mowbray Building Society",
"27" => "Penrith Building Society", "21" => "Nationwide Building Society",
"28" => "Pepper Homeloans", "22" => "Natwest",
"29" => "Royal Bank of Scotland", "23" => "Nedbank Private Wealth",
"30" => "Santander", "24" => "Newbury Building Society",
"31" => "Skipton Building Society", "25" => "OneSavings Bank",
"32" => "Teachers Building Society", "26" => "Parity Trust",
"33" => "The Co-operative Bank", "27" => "Penrith Building Society",
"34" => "Tipton & Coseley Building Society", "28" => "Pepper Homeloans",
"35" => "TSB", "29" => "Royal Bank of Scotland",
"36" => "Ulster Bank", "30" => "Santander",
"37" => "Virgin Money", "31" => "Skipton Building Society",
"38" => "West Bromwich Building Society", "32" => "Teachers Building Society",
"39" => "Yorkshire Building Society", "33" => "The Co-operative Bank",
"40" => "Other", "34" => "Tipton & Coseley Building Society",
}) "35" => "TSB",
"36" => "Ulster Bank",
"37" => "Virgin Money",
"38" => "West Bromwich Building Society",
"39" => "Yorkshire Building Society",
"41" => "Kent Reliance",
"40" => "Other",
})
end
it "has the correct displayed_answer_options" do
expect(question.displayed_answer_options(nil, nil)).to eq({
"" => "Select an option",
"1" => "Atom Bank",
"2" => "Barclays Bank PLC",
"3" => "Bath Building Society",
"4" => "Buckinghamshire Building Society",
"5" => "Cambridge Building Society",
"6" => "Coventry Building Society",
"7" => "Cumberland Building Society",
"8" => "Darlington Building Society",
"9" => "Dudley Building Society",
"10" => "Ecology Building Society",
"11" => "Halifax",
"12" => "Hanley Economic Building Society",
"13" => "Hinckley and Rugby Building Society",
"14" => "Holmesdale Building Society",
"15" => "Ipswich Building Society",
"16" => "Leeds Building Society",
"17" => "Lloyds Bank",
"18" => "Mansfield Building Society",
"19" => "Market Harborough Building Society",
"20" => "Melton Mowbray Building Society",
"21" => "Nationwide Building Society",
"22" => "Natwest",
"23" => "Nedbank Private Wealth",
"24" => "Newbury Building Society",
"25" => "OneSavings Bank",
"26" => "Parity Trust",
"27" => "Penrith Building Society",
"28" => "Pepper Homeloans",
"29" => "Royal Bank of Scotland",
"30" => "Santander",
"31" => "Skipton Building Society",
"32" => "Teachers Building Society",
"33" => "The Co-operative Bank",
"34" => "Tipton & Coseley Building Society",
"35" => "TSB",
"36" => "Ulster Bank",
"37" => "Virgin Money",
"38" => "West Bromwich Building Society",
"39" => "Yorkshire Building Society",
"41" => "Kent Reliance",
"40" => "Other",
})
end
end end
end end

4
spec/models/form/sales/questions/nationality_all_group_spec.rb

@ -47,7 +47,7 @@ RSpec.describe Form::Sales::Questions::NationalityAllGroup, type: :model do
end end
it "has the correct hint" do it "has the correct hint" do
expect(question.hint_text).to eq "Buyer 1 is the person in the household who does the most paid work. If it’s a joint purchase and the buyers do the same amount of paid work, buyer 1 is whoever is the oldest." expect(question.hint_text).to eq "Buyer 1 is the person in the household who does the most paid work. If it’s a joint purchase and the buyers do the same amount of paid work, buyer 1 is whoever is the oldest. If buyer 1 is a dual national of the United Kingdom and another country, enter United Kingdom. If they are a dual national of two other countries, the buyer should decide which country to enter."
end end
it "has the correct header" do it "has the correct header" do
@ -75,7 +75,7 @@ RSpec.describe Form::Sales::Questions::NationalityAllGroup, type: :model do
end end
it "has the correct hint" do it "has the correct hint" do
expect(question.hint_text).to eq("") expect(question.hint_text).to eq "If buyer 2 is a dual national of the United Kingdom and another country, enter United Kingdom. If they are a dual national of two other countries, the buyer should decide which country to enter."
end end
it "has the correct header" do it "has the correct header" do

42
spec/models/form/sales/questions/privacy_notice_spec.rb

@ -6,6 +6,14 @@ RSpec.describe Form::Sales::Questions::PrivacyNotice, type: :model do
let(:question_id) { nil } let(:question_id) { nil }
let(:question_definition) { nil } let(:question_definition) { nil }
let(:page) { instance_double(Form::Page) } let(:page) { instance_double(Form::Page) }
let(:subsection) { instance_double(Form::Subsection) }
let(:form) { instance_double(Form) }
before do
allow(form).to receive(:start_year_after_2024?)
allow(page).to receive(:subsection).and_return(subsection)
allow(subsection).to receive(:form).and_return(form)
end
it "has correct page" do it "has correct page" do
expect(question.page).to eq(page) expect(question.page).to eq(page)
@ -35,10 +43,36 @@ RSpec.describe Form::Sales::Questions::PrivacyNotice, type: :model do
expect(question.hint_text).to be_nil expect(question.hint_text).to be_nil
end end
it "has the correct answer_options" do context "when the form year is before 2024" do
expect(question.answer_options).to eq({ before do
"privacynotice" => { "value" => "The buyer has seen the DLUHC privacy notice" }, allow(form).to receive(:start_year_after_2024?).and_return(false)
}) end
it "has the correct answer_options" do
expect(question.answer_options).to eq({
"privacynotice" => { "value" => "The buyer has seen the DLUHC privacy notice" },
})
end
it "uses the expected top guidance partial" do
expect(question.top_guidance_partial).to eq("privacy_notice_buyer")
end
end
context "when the form year is >= 2024" do
before do
allow(form).to receive(:start_year_after_2024?).and_return(true)
end
it "has the correct answer_options" do
expect(question.answer_options).to eq({
"privacynotice" => { "value" => "The buyer has seen or been given access to the DLUHC privacy notice" },
})
end
it "uses the expected top guidance partial" do
expect(question.top_guidance_partial).to eq("privacy_notice_buyer_2024")
end
end end
it "returns correct unanswered_error_message" do it "returns correct unanswered_error_message" do

1
spec/models/form/sales/subsections/household_characteristics_spec.rb

@ -240,7 +240,6 @@ RSpec.describe Form::Sales::Subsections::HouseholdCharacteristics, type: :model
it "has correct pages" do it "has correct pages" do
expect(household_characteristics.pages.map(&:id)).to eq( expect(household_characteristics.pages.map(&:id)).to eq(
%w[ %w[
privacy_notice
buyer_1_age buyer_1_age
age_1_retirement_value_check age_1_retirement_value_check
age_1_old_persons_shared_ownership_value_check age_1_old_persons_shared_ownership_value_check

1
spec/models/form/sales/subsections/setup_spec.rb

@ -68,6 +68,7 @@ RSpec.describe Form::Sales::Subsections::Setup, type: :model do
joint_purchase joint_purchase
number_joint_buyers number_joint_buyers
buyer_interview buyer_interview
privacy_notice
], ],
) )
end end

4
spec/models/form/sales/subsections/shared_ownership_scheme_spec.rb

@ -7,6 +7,10 @@ RSpec.describe Form::Sales::Subsections::SharedOwnershipScheme, type: :model do
let(:subsection_definition) { nil } let(:subsection_definition) { nil }
let(:section) { instance_double(Form::Sales::Sections::SaleInformation) } let(:section) { instance_double(Form::Sales::Sections::SaleInformation) }
before do
allow(section).to receive(:form).and_return(instance_double(Form, start_year_after_2024?: false))
end
it "has correct section" do it "has correct section" do
expect(shared_ownership_scheme.section).to eq(section) expect(shared_ownership_scheme.section).to eq(section)
end end

94
spec/models/form_handler_spec.rb

@ -271,7 +271,7 @@ RSpec.describe FormHandler do
sales_form = FormFactory.new(year: 1936, type: "sales") sales_form = FormFactory.new(year: 1936, type: "sales")
.with_sections([section]) .with_sections([section])
.build .build
described_class.instance.use_fake_forms!({ only_sales: sales_form }) described_class.instance.use_fake_forms!({ "current_sales" => sales_form })
expect(result).to(satisfy { |result| result.all? { |element| element.is_a?(Form::Question) } }) expect(result).to(satisfy { |result| result.all? { |element| element.is_a?(Form::Question) } })
end end
@ -281,7 +281,7 @@ RSpec.describe FormHandler do
sales_form = FormFactory.new(year: 1936, type: "sales") sales_form = FormFactory.new(year: 1936, type: "sales")
.with_sections([first_section, second_section]) .with_sections([first_section, second_section])
.build .build
described_class.instance.use_fake_forms!({ only_sales: sales_form }) described_class.instance.use_fake_forms!({ "current_sales" => sales_form })
expect(result.map(&:id)).to eq %w[1 2 3 4 5] expect(result.map(&:id)).to eq %w[1 2 3 4 5]
end end
@ -291,7 +291,7 @@ RSpec.describe FormHandler do
sales_form = FormFactory.new(year: 1945, type: "sales") sales_form = FormFactory.new(year: 1945, type: "sales")
.with_sections([first_section, second_section]) .with_sections([first_section, second_section])
.build .build
described_class.instance.use_fake_forms!({ only_sales: sales_form }) described_class.instance.use_fake_forms!({ "current_sales" => sales_form })
expect(result.map(&:id)).to eq %w[1 2 3 4 5 6] expect(result.map(&:id)).to eq %w[1 2 3 4 5 6]
end end
@ -305,12 +305,49 @@ RSpec.describe FormHandler do
.with_sections([new_section]) .with_sections([new_section])
.build .build
fake_forms = { fake_forms = {
earlier_sales: original_form, "previous_sales" => original_form,
newer_sales: new_form, "current_sales" => new_form,
} }
described_class.instance.use_fake_forms!(fake_forms) described_class.instance.use_fake_forms!(fake_forms)
expect(result.map(&:id)).to eq %w[1 1a_deprecated 2 2a_new 3] expect(result.map(&:id)).to eq %w[1 1a_deprecated 2 2a_new 3]
end end
it "inserts questions from previous years that would start a section after new questions in the previous section" do
original_first_section = build(:section)
original_first_section.subsections = [build(:subsection, :with_questions, question_ids: %w[1 2], id: "1", section: original_first_section)]
new_first_section = build(:section)
new_first_section.subsections = [build(:subsection, :with_questions, question_ids: %w[1 2 extra], id: "1", section: new_first_section)]
original_second_section = build(:section)
original_second_section.subsections = [build(:subsection, :with_questions, question_ids: %w[3 4], id: "2")]
new_second_section = build(:section)
new_second_section.subsections = [build(:subsection, :with_questions, question_ids: %w[3_new 4], id: "2")]
original_form = FormFactory.new(year: 2022, type: "sales").with_sections([original_first_section, original_second_section]).build
new_form = FormFactory.new(year: 2023, type: "sales").with_sections([new_first_section, new_second_section]).build
fake_forms = {
"current_sales" => new_form,
"previous_sales" => original_form,
}
described_class.instance.use_fake_forms!(fake_forms)
expect(result.map(&:id)).to eq %w[1 2 extra 3 3_new 4]
end
it "builds the ordering based on the current form" do
archived_section = build(:section, :with_questions, question_ids: %w[0 1 2 3])
previous_section = build(:section, :with_questions, question_ids: %w[0 1 3 2])
current_section = build(:section, :with_questions, question_ids: %w[3 2 0 1])
next_section = build(:section, :with_questions, question_ids: %w[3 2 1 0])
fake_forms = {
"current_sales" => FormFactory.new(year: 2023, type: "sales").with_sections([current_section]).build,
"previous_sales" => FormFactory.new(year: 2022, type: "sales").with_sections([previous_section]).build,
"next_sales" => FormFactory.new(year: 2021, type: "sales").with_sections([next_section]).build,
"archived_sales" => FormFactory.new(year: 2020, type: "sales").with_sections([archived_section]).build,
}
described_class.instance.use_fake_forms!(fake_forms)
expect(result.map(&:id)).to eq %w[3 2 0 1]
end
end end
describe "#ordered_lettings_questions_for_all_years" do describe "#ordered_lettings_questions_for_all_years" do
@ -322,7 +359,7 @@ RSpec.describe FormHandler do
lettings_form = FormFactory.new(year: 2936, type: "lettings") lettings_form = FormFactory.new(year: 2936, type: "lettings")
.with_sections([section]) .with_sections([section])
.build .build
described_class.instance.use_fake_forms!({ only_lettings: lettings_form }) described_class.instance.use_fake_forms!({ "current_lettings" => lettings_form })
expect(result).to(satisfy { |result| result.all? { |element| element.is_a?(Form::Question) } }) expect(result).to(satisfy { |result| result.all? { |element| element.is_a?(Form::Question) } })
end end
@ -332,7 +369,7 @@ RSpec.describe FormHandler do
lettings_form = FormFactory.new(year: 2936, type: "lettings") lettings_form = FormFactory.new(year: 2936, type: "lettings")
.with_sections([first_section, second_section]) .with_sections([first_section, second_section])
.build .build
described_class.instance.use_fake_forms!({ only_lettings: lettings_form }) described_class.instance.use_fake_forms!({ "current_lettings" => lettings_form })
expect(result.map(&:id)).to eq %w[1 2 3 4 5] expect(result.map(&:id)).to eq %w[1 2 3 4 5]
end end
@ -342,7 +379,7 @@ RSpec.describe FormHandler do
lettings_form = FormFactory.new(year: 2945, type: "lettings") lettings_form = FormFactory.new(year: 2945, type: "lettings")
.with_sections([first_section, second_section]) .with_sections([first_section, second_section])
.build .build
described_class.instance.use_fake_forms!({ only_lettings: lettings_form }) described_class.instance.use_fake_forms!({ "current_lettings" => lettings_form })
expect(result.map(&:id)).to eq %w[1 2 3 4 5 6] expect(result.map(&:id)).to eq %w[1 2 3 4 5 6]
end end
@ -356,12 +393,49 @@ RSpec.describe FormHandler do
.with_sections([new_section]) .with_sections([new_section])
.build .build
fake_forms = { fake_forms = {
earlier_lettings: original_form, "previous_lettings" => original_form,
newer_lettings: new_form, "current_lettings" => new_form,
} }
described_class.instance.use_fake_forms!(fake_forms) described_class.instance.use_fake_forms!(fake_forms)
expect(result.map(&:id)).to eq %w[1 1a_deprecated 2 2a_new 3] expect(result.map(&:id)).to eq %w[1 1a_deprecated 2 2a_new 3]
end end
it "inserts questions from previous years that would start a section after new questions in the previous section" do
original_first_section = build(:section)
original_first_section.subsections = [build(:subsection, :with_questions, question_ids: %w[1 2], id: "1", section: original_first_section)]
new_first_section = build(:section)
new_first_section.subsections = [build(:subsection, :with_questions, question_ids: %w[1 2 extra], id: "1", section: new_first_section)]
original_second_section = build(:section)
original_second_section.subsections = [build(:subsection, :with_questions, question_ids: %w[3 4], id: "2")]
new_second_section = build(:section)
new_second_section.subsections = [build(:subsection, :with_questions, question_ids: %w[3_new 4], id: "2")]
original_form = FormFactory.new(year: 2023, type: "lettings").with_sections([original_first_section, original_second_section]).build
new_form = FormFactory.new(year: 2024, type: "lettings").with_sections([new_first_section, new_second_section]).build
fake_forms = {
"current_lettings" => new_form,
"previous_lettings" => original_form,
}
described_class.instance.use_fake_forms!(fake_forms)
expect(result.map(&:id)).to eq %w[1 2 extra 3 3_new 4]
end
it "builds the ordering based on the current form" do
archived_section = build(:section, :with_questions, question_ids: %w[0 1 2 3])
previous_section = build(:section, :with_questions, question_ids: %w[0 1 3 2])
current_section = build(:section, :with_questions, question_ids: %w[3 2 0 1])
next_section = build(:section, :with_questions, question_ids: %w[3 2 1 0])
fake_forms = {
"current_lettings" => FormFactory.new(year: 2023, type: "sales").with_sections([current_section]).build,
"previous_lettings" => FormFactory.new(year: 2022, type: "sales").with_sections([previous_section]).build,
"next_lettings" => FormFactory.new(year: 2021, type: "sales").with_sections([next_section]).build,
"archived_lettings" => FormFactory.new(year: 2020, type: "sales").with_sections([archived_section]).build,
}
described_class.instance.use_fake_forms!(fake_forms)
expect(result.map(&:id)).to eq %w[3 2 0 1]
end
end end
# rubocop:enable RSpec/PredicateMatcher # rubocop:enable RSpec/PredicateMatcher
end end

54
spec/models/sales_log_spec.rb

@ -657,7 +657,7 @@ RSpec.describe SalesLog, type: :model do
end end
before do before do
WebMock.stub_request(:get, /api.postcodes.io\/postcodes\/CA101AA/) WebMock.stub_request(:get, /api\.postcodes\.io\/postcodes\/CA101AA/)
.to_return(status: 200, body: '{"status":200,"result":{"admin_district":"Cumberland","codes":{"admin_district":"E06000064"}}}', headers: {}) .to_return(status: 200, body: '{"status":200,"result":{"admin_district":"Cumberland","codes":{"admin_district":"E06000064"}}}', headers: {})
Timecop.freeze(2023, 5, 1) Timecop.freeze(2023, 5, 1)
@ -687,7 +687,7 @@ RSpec.describe SalesLog, type: :model do
end end
before do before do
WebMock.stub_request(:get, /api.postcodes.io\/postcodes\/CA101AA/) WebMock.stub_request(:get, /api\.postcodes\.io\/postcodes\/CA101AA/)
.to_return(status: 200, body: '{"status":200,"result":{"admin_district":"Eden","codes":{"admin_district":"E07000030"}}}', headers: {}) .to_return(status: 200, body: '{"status":200,"result":{"admin_district":"Eden","codes":{"admin_district":"E07000030"}}}', headers: {})
Timecop.freeze(2023, 5, 2) Timecop.freeze(2023, 5, 2)
@ -703,6 +703,56 @@ RSpec.describe SalesLog, type: :model do
expect(address_sales_log_23_24.la).to eq("E06000064") expect(address_sales_log_23_24.la).to eq("E06000064")
expect(record_from_db["la"]).to eq("E06000064") expect(record_from_db["la"]).to eq("E06000064")
end end
it "does not set previous postcode or previous la for discounted sale" do
address_sales_log_23_24.update!(ownershipsch: 2, ppostcode_full: nil, prevloc: nil)
record_from_db = described_class.find(address_sales_log_23_24.id)
expect(address_sales_log_23_24.ppostcode_full).to eq(nil)
expect(record_from_db["ppostcode_full"]).to eq(nil)
expect(record_from_db["prevloc"]).to eq(nil)
end
end
context "with 24/25 logs" do
let(:address_sales_log_24_25) do
described_class.create({
owning_organisation:,
created_by: created_by_user,
ppcodenk: 1,
postcode_full: "CA10 1AA",
ppostcode_full: nil,
prevloc: nil,
saledate: Time.zone.local(2024, 5, 2),
})
end
before do
WebMock.stub_request(:get, /api\.postcodes\.io\/postcodes\/CA101AA/)
.to_return(status: 200, body: '{"status":200,"result":{"admin_district":"Eden","codes":{"admin_district":"E07000030"}}}', headers: {})
Timecop.freeze(2024, 5, 2)
Singleton.__init__(FormHandler)
end
after do
Timecop.unfreeze
end
it "sets previous postcode for discounted sale" do
address_sales_log_24_25.update!(ownershipsch: 2, ppostcode_full: nil)
record_from_db = described_class.find(address_sales_log_24_25.id)
expect(address_sales_log_24_25.ppostcode_full).to eq("CA10 1AA")
expect(record_from_db["ppostcode_full"]).to eq("CA10 1AA")
expect(record_from_db["prevloc"]).to eq("E06000064")
end
it "does not set previous postcode for non discounted sale" do
address_sales_log_24_25.update!(ownershipsch: 1, ppostcode_full: nil)
record_from_db = described_class.find(address_sales_log_24_25.id)
expect(address_sales_log_24_25.ppostcode_full).to eq(nil)
expect(record_from_db["ppostcode_full"]).to eq(nil)
expect(record_from_db["prevloc"]).to eq(nil)
end
end end
it "errors if the property postcode is emptied" do it "errors if the property postcode is emptied" do

21
spec/models/validations/financial_validations_spec.rb

@ -188,6 +188,7 @@ RSpec.describe Validations::FinancialValidations do
describe "net income validations" do describe "net income validations" do
it "validates that the net income is within the expected range for the household’s employment status" do it "validates that the net income is within the expected range for the household’s employment status" do
record.startdate = Time.zone.local(2023, 5, 1)
record.earnings = 200 record.earnings = 200
record.incfreq = 1 record.incfreq = 1
record.hhmemb = 1 record.hhmemb = 1
@ -198,6 +199,7 @@ RSpec.describe Validations::FinancialValidations do
context "when the net income is higher than the hard max for their employment status" do context "when the net income is higher than the hard max for their employment status" do
it "adds an error" do it "adds an error" do
record.startdate = Time.zone.local(2023, 5, 1)
record.earnings = 5000 record.earnings = 5000
record.incfreq = 1 record.incfreq = 1
record.hhmemb = 1 record.hhmemb = 1
@ -214,6 +216,7 @@ RSpec.describe Validations::FinancialValidations do
context "when the net income is lower than the hard min for their employment status" do context "when the net income is lower than the hard min for their employment status" do
it "adds an error" do it "adds an error" do
record.startdate = Time.zone.local(2023, 5, 1)
record.earnings = 50 record.earnings = 50
record.incfreq = 1 record.incfreq = 1
record.hhmemb = 1 record.hhmemb = 1
@ -230,6 +233,7 @@ RSpec.describe Validations::FinancialValidations do
context "when there is more than one household member" do context "when there is more than one household member" do
it "allows income levels based on all working situations combined" do it "allows income levels based on all working situations combined" do
record.startdate = Time.zone.local(2023, 5, 1)
record.earnings = 5000 record.earnings = 5000
record.incfreq = 1 record.incfreq = 1
record.hhmemb = 4 record.hhmemb = 4
@ -242,6 +246,7 @@ RSpec.describe Validations::FinancialValidations do
end end
it "uses the combined value in error messages" do it "uses the combined value in error messages" do
record.startdate = Time.zone.local(2023, 5, 1)
record.earnings = 100 record.earnings = 100
record.incfreq = 1 record.incfreq = 1
record.hhmemb = 3 record.hhmemb = 3
@ -254,6 +259,7 @@ RSpec.describe Validations::FinancialValidations do
end end
it "adds errors to relevant fields for each tenant when income is too high" do it "adds errors to relevant fields for each tenant when income is too high" do
record.startdate = Time.zone.local(2023, 5, 1)
record.earnings = 5000 record.earnings = 5000
record.incfreq = 1 record.incfreq = 1
record.hhmemb = 3 record.hhmemb = 3
@ -277,6 +283,7 @@ RSpec.describe Validations::FinancialValidations do
end end
it "adds errors to relevant fields for each tenant when income is too low" do it "adds errors to relevant fields for each tenant when income is too low" do
record.startdate = Time.zone.local(2023, 5, 1)
record.earnings = 50 record.earnings = 50
record.incfreq = 1 record.incfreq = 1
record.hhmemb = 3 record.hhmemb = 3
@ -293,6 +300,20 @@ RSpec.describe Validations::FinancialValidations do
expect(record.errors["ecstat#{n}"]).to be_empty expect(record.errors["ecstat#{n}"]).to be_empty
end end
end end
context "when the net income is lower than the hard min for their employment status for 22/23 collection" do
it "does not add an error" do
record.startdate = Time.zone.local(2022, 5, 1)
record.earnings = 50
record.incfreq = 1
record.hhmemb = 1
record.ecstat1 = 1
financial_validator.validate_net_income(record)
expect(record.errors["earnings"]).to be_empty
expect(record.errors["ecstat1"]).to be_empty
expect(record.errors["hhmemb"]).to be_empty
end
end
end end
end end

58
spec/models/validations/sales/household_validations_spec.rb

@ -154,64 +154,6 @@ RSpec.describe Validations::Sales::HouseholdValidations do
end end
end end
describe "previous postcode validations" do
let(:record) { build(:sales_log) }
context "with a discounted sale" do
before do
record.ownershipsch = 2
end
it "adds an error when previous and current postcodes are not the same" do
record.postcode_full = "SO32 3PT"
record.ppostcode_full = "DN6 7FB"
household_validator.validate_previous_postcode(record)
expect(record.errors["postcode_full"])
.to include(match I18n.t("validations.household.postcode.discounted_ownership"))
expect(record.errors["ppostcode_full"])
.to include(match I18n.t("validations.household.postcode.discounted_ownership"))
end
it "allows same postcodes" do
record.postcode_full = "SO32 3PT"
record.ppostcode_full = "SO32 3PT"
household_validator.validate_previous_postcode(record)
expect(record.errors["postcode_full"]).to be_empty
expect(record.errors["ppostcode_full"]).to be_empty
end
it "does not add an error when postcode is missing" do
record.postcode_full = nil
record.ppostcode_full = "SO32 3PT"
household_validator.validate_previous_postcode(record)
expect(record.errors["postcode_full"]).to be_empty
expect(record.errors["ppostcode_full"]).to be_empty
end
it "does not add an error when previous postcode is missing" do
record.postcode_full = "SO32 3PT"
record.ppostcode_full = nil
household_validator.validate_previous_postcode(record)
expect(record.errors["postcode_full"]).to be_empty
expect(record.errors["ppostcode_full"]).to be_empty
end
end
context "without a discounted sale" do
before do
record.ownershipsch = 1
end
it "allows different postcodes" do
record.postcode_full = "SO32 3PT"
record.ppostcode_full = "DN6 7FB"
household_validator.validate_previous_postcode(record)
expect(record.errors["postcode_full"]).to be_empty
expect(record.errors["ppostcode_full"]).to be_empty
end
end
end
describe "validating fields about buyers living in the property" do describe "validating fields about buyers living in the property" do
let(:sales_log) { FactoryBot.create(:sales_log, :outright_sale_setup_complete, noint: 1, companybuy: 2, buylivein:, jointpur:, jointmore:, buy1livein:) } let(:sales_log) { FactoryBot.create(:sales_log, :outright_sale_setup_complete, noint: 1, companybuy: 2, buylivein:, jointpur:, jointmore:, buy1livein:) }

12
spec/models/validations/sales/property_validations_spec.rb

@ -19,7 +19,7 @@ RSpec.describe Validations::Sales::PropertyValidations do
end end
context "when ownership scheme is discounted ownership" do context "when ownership scheme is discounted ownership" do
let(:record) { build(:sales_log, ownershipsch: 2) } let(:record) { build(:sales_log, ownershipsch: 2, saledate: Time.zone.local(2023, 4, 5)) }
it "when ppostcode_full is not present no error is added" do it "when ppostcode_full is not present no error is added" do
record.postcode_full = "SW1A 1AA" record.postcode_full = "SW1A 1AA"
@ -54,6 +54,16 @@ RSpec.describe Validations::Sales::PropertyValidations do
expect(record.errors["ppostcode_full"]).to include(match I18n.t("validations.property.postcode.must_match_previous")) expect(record.errors["ppostcode_full"]).to include(match I18n.t("validations.property.postcode.must_match_previous"))
expect(record.errors["ownershipsch"]).to include(match I18n.t("validations.property.postcode.must_match_previous")) expect(record.errors["ownershipsch"]).to include(match I18n.t("validations.property.postcode.must_match_previous"))
end end
it "does not add error for 2024 log" do
record.postcode_full = "SW1A 1AA"
record.ppostcode_full = "SW1A 0AA"
record.saledate = Time.zone.local(2024, 4, 5)
property_validator.validate_postcodes_match_if_discounted_ownership(record)
expect(record.errors["postcode_full"]).to be_empty
expect(record.errors["ppostcode_full"]).to be_empty
expect(record.errors["ownershipsch"]).to be_empty
end
end end
end end

44
spec/models/validations/sales/sale_information_validations_spec.rb

@ -756,4 +756,48 @@ RSpec.describe Validations::Sales::SaleInformationValidations do
end end
end end
end end
describe "#validate_mortgage_used_and_stairbought" do
let(:now) { Time.zone.local(2024, 4, 4) }
before do
Timecop.freeze(now)
Singleton.__init__(FormHandler)
end
after do
Timecop.return
Singleton.__init__(FormHandler)
end
context "when mortgageused don't know" do
let(:record) { build(:sales_log, ownershipsch: 1, type: 9, saledate: now, mortgageused: 3) }
it "does not add an error if stairowned 100" do
record.stairowned = 100
sale_information_validator.validate_mortgage_used_and_stairbought(record)
expect(record.errors).to be_empty
end
it "adds an error if stairowned is not 100" do
record.stairowned = 90
sale_information_validator.validate_mortgage_used_and_stairbought(record)
expect(record.errors[:stairowned]).to include("The percentage owned has to be 100% if the mortgage used is 'Don’t know'")
expect(record.errors[:mortgageused]).to include("The percentage owned has to be 100% if the mortgage used is 'Don’t know'")
end
end
context "when the collection year is before 2024" do
let(:record) { build(:sales_log, ownershipsch: 1, type: 9, saledate: now, mortgageused: 3, stairowned: 90) }
let(:now) { Time.zone.local(2023, 4, 4) }
it "does not add an error" do
sale_information_validator.validate_mortgage_used_and_stairbought(record)
expect(record.errors).to be_empty
end
end
end
end end

17
spec/requests/bulk_upload_lettings_resume_controller_spec.rb

@ -211,5 +211,22 @@ RSpec.describe BulkUploadLettingsResumeController, type: :request do
expect(response).to redirect_to("/lettings-logs/bulk-upload-soft-validations-check/#{bulk_upload.id}/chosen") expect(response).to redirect_to("/lettings-logs/bulk-upload-soft-validations-check/#{bulk_upload.id}/chosen")
end end
end end
context "and has a row with all non-cleared errors" do
let(:bulk_upload_errors) { [create(:bulk_upload_error, row: 1), create(:bulk_upload_error, row: 2, category: :not_answered), create(:bulk_upload_error, row: 3, category: :soft_validation), create(:bulk_upload_error, row: 4)] }
let(:bulk_upload) { create(:bulk_upload, :lettings, user:, bulk_upload_errors:) }
it "renders the page correctly" do
get "/lettings-logs/bulk-upload-resume/#{bulk_upload.id}/deletion-report"
expect(response).to be_successful
expect(response.body).to include("Bulk upload for lettings")
expect(response.body).to include("2023/24")
expect(response.body).to include("These 2 answers will be deleted if you upload the log")
expect(response.body).to include(bulk_upload.filename)
expect(response.body).to include("Clear this data and upload the logs")
end
end
end end
end end

17
spec/requests/bulk_upload_sales_resume_controller_spec.rb

@ -211,5 +211,22 @@ RSpec.describe BulkUploadSalesResumeController, type: :request do
expect(response).to redirect_to("/sales-logs/bulk-upload-soft-validations-check/#{bulk_upload.id}/chosen") expect(response).to redirect_to("/sales-logs/bulk-upload-soft-validations-check/#{bulk_upload.id}/chosen")
end end
end end
context "and has a row with all non-cleared errors" do
let(:bulk_upload_errors) { [create(:bulk_upload_error, row: 1), create(:bulk_upload_error, row: 2, category: :not_answered), create(:bulk_upload_error, row: 3, category: :soft_validation), create(:bulk_upload_error, row: 4)] }
let(:bulk_upload) { create(:bulk_upload, :sales, user:, bulk_upload_errors:) }
it "renders the page correctly" do
get "/sales-logs/bulk-upload-resume/#{bulk_upload.id}/deletion-report"
expect(response).to be_successful
expect(response.body).to include("Bulk upload for sales")
expect(response.body).to include("2023/24")
expect(response.body).to include("These 2 answers will be deleted if you upload the log")
expect(response.body).to include(bulk_upload.filename)
expect(response.body).to include("Clear this data and upload the logs")
end
end
end end
end end

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

@ -1119,6 +1119,7 @@ RSpec.describe BulkUpload::Lettings::Year2024::RowParser do
expect(parser.errors[:field_112]).to include("You must answer was the letting made under the Choice-Based Lettings (CBL)?") expect(parser.errors[:field_112]).to include("You must answer was the letting made under the Choice-Based Lettings (CBL)?")
expect(parser.errors[:field_113]).to include("You must answer was the letting made under the Common Allocation Policy (CAP)?") expect(parser.errors[:field_113]).to include("You must answer was the letting made under the Common Allocation Policy (CAP)?")
expect(parser.errors[:field_114]).to include("You must answer was the letting made under the Common Housing Register (CHR)?") expect(parser.errors[:field_114]).to include("You must answer was the letting made under the Common Housing Register (CHR)?")
expect(parser.errors[:field_115]).to include("You must answer was the letting made under the Accessible Register?")
end end
end end
end end
@ -1889,16 +1890,16 @@ RSpec.describe BulkUpload::Lettings::Year2024::RowParser do
end end
describe "#letting_allocation_unknown" do describe "#letting_allocation_unknown" do
context "when field_112, 117, 118 are no ie 2" do context "when field_112, 113, 114, 115 are no ie 2" do
let(:attributes) { { bulk_upload:, field_112: 2, field_113: 2, field_114: 2 } } let(:attributes) { { bulk_upload:, field_112: 2, field_113: 2, field_114: 2, field_115: 2 } }
it "sets value to 1" do it "sets value to 1" do
expect(parser.log.letting_allocation_unknown).to be(1) expect(parser.log.letting_allocation_unknown).to be(1)
end end
end end
context "when any one of field_112, 117, 118 is yes ie 1" do context "when any one of field_112, 113, 114, 115 is yes ie 1" do
let(:attributes) { { bulk_upload:, field_112: 1 } } let(:attributes) { { bulk_upload:, field_115: 1 } }
it "sets value to 0" do it "sets value to 0" do
expect(parser.log.letting_allocation_unknown).to be(0) expect(parser.log.letting_allocation_unknown).to be(0)

30
spec/services/bulk_upload/sales/year2024/row_parser_spec.rb

@ -975,6 +975,36 @@ RSpec.describe BulkUpload::Sales::Year2024::RowParser do
end end
end end
describe "#field_103" do # shared ownership mortgageused
context "when invalid value" do
let(:attributes) { setup_section_params.merge(field_103: "4") }
it "returns correct errors" do
expect(parser.errors[:field_103]).to include("Enter a valid value for Was a mortgage used for the purchase of this property? - Shared ownership")
end
end
context "when value is 3 and stairowned is not 100" do
let(:attributes) { setup_section_params.merge(field_103: "3", field_86: "1", field_87: "50", field_88: "99", field_109: nil) }
it "returns correct errors" do
expect(parser.errors[:field_103]).to include("Enter a valid value for Was a mortgage used for the purchase of this property? - Shared ownership")
end
end
context "when value is 3 and stairowned is 100" do
let(:attributes) { setup_section_params.merge(field_103: "3", field_86: "1", field_87: "50", field_88: "100", field_109: nil) }
it "does not add errors and sets mortgage used to 3" do
expect(parser.log.mortgageused).to be(3)
expect(parser.log.stairowned).to be(100)
expect(parser.log.deposit).to be(nil)
expect(parser.errors[:field_103]).to be_empty
expect(parser.errors[:field_109]).to be_empty
end
end
end
describe "soft validations" do describe "soft validations" do
context "when soft validation is triggered" do context "when soft validation is triggered" do
let(:attributes) { valid_attributes.merge({ field_31: 22, field_35: 5 }) } let(:attributes) { valid_attributes.merge({ field_31: 22, field_35: 5 }) }

143
spec/services/csv/lettings_log_csv_service_spec.rb

@ -2,7 +2,7 @@ require "rails_helper"
RSpec.describe Csv::LettingsLogCsvService do RSpec.describe Csv::LettingsLogCsvService do
before do before do
Timecop.freeze(fixed_time) Timecop.freeze(now)
Singleton.__init__(FormHandler) Singleton.__init__(FormHandler)
FormHandler.instance.use_real_forms! FormHandler.instance.use_real_forms!
log.irproduct = 1 log.irproduct = 1
@ -17,13 +17,14 @@ RSpec.describe Csv::LettingsLogCsvService do
let(:form_handler_mock) { instance_double(FormHandler) } let(:form_handler_mock) { instance_double(FormHandler) }
let(:organisation) { create(:organisation) } let(:organisation) { create(:organisation) }
let(:fixed_time) { Time.zone.local(2023, 11, 26) } let(:fixed_time) { Time.zone.local(2023, 11, 26) }
let(:now) { Time.zone.now }
let(:log) do let(:log) do
create( create(
:lettings_log, :lettings_log,
:completed, :completed,
startdate: fixed_time, startdate: fixed_time,
created_at: fixed_time, created_at: fixed_time,
updated_at: fixed_time, updated_at: now,
mrcdate: fixed_time - 1.day, mrcdate: fixed_time - 1.day,
voiddate: fixed_time - 2.days, voiddate: fixed_time - 2.days,
propcode: "ABCDEFG", propcode: "ABCDEFG",
@ -100,7 +101,7 @@ RSpec.describe Csv::LettingsLogCsvService do
let(:questions) do let(:questions) do
[ [
build(:question, id: "condition_effects", type: "checkbox", answer_options: { "illness_type_1" => {}, "illness_type_2" => {}, "illness_type_3" => {} }), build(:question, id: "condition_effects", type: "checkbox", answer_options: { "illness_type_1" => {}, "illness_type_2" => {}, "illness_type_3" => {} }),
build(:question, id: "letting_allocation", type: "checkbox", answer_options: { "cbl" => {}, "cap" => {}, "chr" => {} }), build(:question, id: "letting_allocation", type: "checkbox", answer_options: { "cbl" => {}, "cap" => {}, "chr" => {}, "accessible_register" => {} }),
] ]
end end
@ -162,14 +163,32 @@ RSpec.describe Csv::LettingsLogCsvService do
expect(la_label_value).to eq "Barnet" expect(la_label_value).to eq "Barnet"
end end
it "exports the CSV with all values correct" do context "when the current form is 2024" do
expected_content = CSV.read("spec/fixtures/files/lettings_log_csv_export_labels.csv") let(:now) { Time.zone.local(2024, 4, 1) }
values_to_delete = %w[id vacdays]
values_to_delete.each do |attribute| it "exports the CSV with 2024 ordering and all values correct" do
index = csv.first.index(attribute) expected_content = CSV.read("spec/fixtures/files/lettings_log_csv_export_labels_24.csv")
csv.second[index] = nil values_to_delete = %w[id vacdays]
values_to_delete.each do |attribute|
index = csv.first.index(attribute)
csv.second[index] = nil
end
expect(csv).to eq expected_content
end
end
context "when the current form is 2023" do
let(:now) { Time.zone.local(2023, 11, 26) }
it "exports the CSV with 2023 ordering and all values correct" do
expected_content = CSV.read("spec/fixtures/files/lettings_log_csv_export_labels_23.csv")
values_to_delete = %w[id vacdays]
values_to_delete.each do |attribute|
index = csv.first.index(attribute)
csv.second[index] = nil
end
expect(csv).to eq expected_content
end end
expect(csv).to eq expected_content
end end
context "when the log has a duplicate log reference" do context "when the log has a duplicate log reference" do
@ -212,14 +231,32 @@ RSpec.describe Csv::LettingsLogCsvService do
expect(la_label_value).to eq "Barnet" expect(la_label_value).to eq "Barnet"
end end
it "exports the CSV with all values correct" do context "when the current form is 2024" do
expected_content = CSV.read("spec/fixtures/files/lettings_log_csv_export_codes.csv") let(:now) { Time.zone.local(2024, 4, 1) }
values_to_delete = %w[id vacdays]
values_to_delete.each do |attribute| it "exports the CSV with all values correct" do
index = csv.first.index(attribute) expected_content = CSV.read("spec/fixtures/files/lettings_log_csv_export_codes_24.csv")
csv.second[index] = nil values_to_delete = %w[id vacdays]
values_to_delete.each do |attribute|
index = csv.first.index(attribute)
csv.second[index] = nil
end
expect(csv).to eq expected_content
end
end
context "when the current form is 2023" do
let(:now) { Time.zone.local(2023, 11, 26) }
it "exports the CSV with all values correct" do
expected_content = CSV.read("spec/fixtures/files/lettings_log_csv_export_codes_23.csv")
values_to_delete = %w[id vacdays]
values_to_delete.each do |attribute|
index = csv.first.index(attribute)
csv.second[index] = nil
end
expect(csv).to eq expected_content
end end
expect(csv).to eq expected_content
end end
context "when the log has a duplicate log reference" do context "when the log has a duplicate log reference" do
@ -242,31 +279,67 @@ RSpec.describe Csv::LettingsLogCsvService do
expect(headers).not_to include(*%w[wrent wscharge wpschrge wsupchrg wtcharge]) expect(headers).not_to include(*%w[wrent wscharge wpschrge wsupchrg wtcharge])
end end
context "and exporting with labels" do context "and the current form is 2024" do
let(:export_type) { "labels" } let(:now) { Time.zone.local(2024, 4, 1) }
it "exports the CSV with all values correct" do context "and exporting with labels" do
expected_content = CSV.read("spec/fixtures/files/lettings_log_csv_export_non_support_labels.csv") let(:export_type) { "labels" }
values_to_delete = %w[id]
values_to_delete.each do |attribute| it "exports the CSV with all values correct" do
index = csv.first.index(attribute) expected_content = CSV.read("spec/fixtures/files/lettings_log_csv_export_non_support_labels_24.csv")
csv.second[index] = nil values_to_delete = %w[id]
values_to_delete.each do |attribute|
index = csv.first.index(attribute)
csv.second[index] = nil
end
expect(csv).to eq expected_content
end
end
context "and exporting values as codes" do
let(:export_type) { "codes" }
it "exports the CSV with all values correct" do
expected_content = CSV.read("spec/fixtures/files/lettings_log_csv_export_non_support_codes_24.csv")
values_to_delete = %w[id]
values_to_delete.each do |attribute|
index = csv.first.index(attribute)
csv.second[index] = nil
end
expect(csv).to eq expected_content
end end
expect(csv).to eq expected_content
end end
end end
context "and exporting values as codes" do context "and the current form is 2023" do
let(:export_type) { "codes" } let(:now) { Time.zone.local(2023, 11, 26) }
it "exports the CSV with all values correct" do context "and exporting with labels" do
expected_content = CSV.read("spec/fixtures/files/lettings_log_csv_export_non_support_codes.csv") let(:export_type) { "labels" }
values_to_delete = %w[id]
values_to_delete.each do |attribute| it "exports the CSV with all values correct" do
index = csv.first.index(attribute) expected_content = CSV.read("spec/fixtures/files/lettings_log_csv_export_non_support_labels_23.csv")
csv.second[index] = nil values_to_delete = %w[id]
values_to_delete.each do |attribute|
index = csv.first.index(attribute)
csv.second[index] = nil
end
expect(csv).to eq expected_content
end
end
context "and exporting values as codes" do
let(:export_type) { "codes" }
it "exports the CSV with all values correct" do
expected_content = CSV.read("spec/fixtures/files/lettings_log_csv_export_non_support_codes_23.csv")
values_to_delete = %w[id]
values_to_delete.each do |attribute|
index = csv.first.index(attribute)
csv.second[index] = nil
end
expect(csv).to eq expected_content
end end
expect(csv).to eq expected_content
end end
end end
end end

73
spec/services/csv/sales_log_csv_service_spec.rb

@ -4,6 +4,7 @@ RSpec.describe Csv::SalesLogCsvService do
let(:form_handler_mock) { instance_double(FormHandler) } let(:form_handler_mock) { instance_double(FormHandler) }
let(:organisation) { create(:organisation) } let(:organisation) { create(:organisation) }
let(:fixed_time) { Time.zone.local(2023, 12, 8) } let(:fixed_time) { Time.zone.local(2023, 12, 8) }
let(:now) { Time.zone.now }
let(:user) { create(:user, email: "billyboy@eyeKLAUD.com") } let(:user) { create(:user, email: "billyboy@eyeKLAUD.com") }
let(:log) do let(:log) do
create( create(
@ -12,7 +13,7 @@ RSpec.describe Csv::SalesLogCsvService do
created_by: user, created_by: user,
saledate: fixed_time, saledate: fixed_time,
created_at: fixed_time, created_at: fixed_time,
updated_at: fixed_time, updated_at: now,
owning_organisation: organisation, owning_organisation: organisation,
purchid: nil, purchid: nil,
hholdcount: 3, hholdcount: 3,
@ -29,11 +30,15 @@ RSpec.describe Csv::SalesLogCsvService do
let(:csv) { CSV.parse(service.prepare_csv(SalesLog.all)) } let(:csv) { CSV.parse(service.prepare_csv(SalesLog.all)) }
before do before do
allow(Time).to receive(:now).and_return(fixed_time) Timecop.freeze(now)
Singleton.__init__(FormHandler) Singleton.__init__(FormHandler)
log log
end end
after do
Timecop.return
end
it "calls the form handler to get all questions in order when initialized" do it "calls the form handler to get all questions in order when initialized" do
allow(FormHandler).to receive(:instance).and_return(form_handler_mock) allow(FormHandler).to receive(:instance).and_return(form_handler_mock)
allow(form_handler_mock).to receive(:ordered_sales_questions_for_all_years).and_return([]) allow(form_handler_mock).to receive(:ordered_sales_questions_for_all_years).and_return([])
@ -154,14 +159,32 @@ RSpec.describe Csv::SalesLogCsvService do
expect(la_label_value).to eq "Barnet" expect(la_label_value).to eq "Barnet"
end end
it "exports the CSV with all values correct" do context "when the current form is 2024" do
expected_content = CSV.read("spec/fixtures/files/sales_logs_csv_export_labels.csv") let(:now) { Time.zone.local(2024, 5, 1) }
values_to_delete = %w[id]
values_to_delete.each do |attribute| it "exports the CSV with the 2024 ordering and all values correct" do
index = csv.first.index(attribute) expected_content = CSV.read("spec/fixtures/files/sales_logs_csv_export_labels_24.csv")
csv.second[index] = nil values_to_delete = %w[id]
values_to_delete.each do |attribute|
index = csv.first.index(attribute)
csv.second[index] = nil
end
expect(csv).to eq expected_content
end
end
context "when the current form is 2023" do
let(:now) { Time.zone.local(2024, 1, 1) }
it "exports the CSV with the 2023 ordering and all values correct" do
expected_content = CSV.read("spec/fixtures/files/sales_logs_csv_export_labels_23.csv")
values_to_delete = %w[id]
values_to_delete.each do |attribute|
index = csv.first.index(attribute)
csv.second[index] = nil
end
expect(csv).to eq expected_content
end end
expect(csv).to eq expected_content
end end
context "when the log has a duplicate log reference" do context "when the log has a duplicate log reference" do
@ -214,14 +237,32 @@ RSpec.describe Csv::SalesLogCsvService do
expect(la_label_value).to eq "Barnet" expect(la_label_value).to eq "Barnet"
end end
it "exports the CSV with all values correct" do context "when the current form is 2024" do
expected_content = CSV.read("spec/fixtures/files/sales_logs_csv_export_codes.csv") let(:now) { Time.zone.local(2024, 5, 1) }
values_to_delete = %w[id]
values_to_delete.each do |attribute| it "exports the CSV with all values correct" do
index = csv.first.index(attribute) expected_content = CSV.read("spec/fixtures/files/sales_logs_csv_export_codes_24.csv")
csv.second[index] = nil values_to_delete = %w[id]
values_to_delete.each do |attribute|
index = csv.first.index(attribute)
csv.second[index] = nil
end
expect(csv).to eq expected_content
end
end
context "when the current form is 2023" do
let(:now) { Time.zone.local(2024, 1, 1) }
it "exports the CSV with all values correct" do
expected_content = CSV.read("spec/fixtures/files/sales_logs_csv_export_codes_23.csv")
values_to_delete = %w[id]
values_to_delete.each do |attribute|
index = csv.first.index(attribute)
csv.second[index] = nil
end
expect(csv).to eq expected_content
end end
expect(csv).to eq expected_content
end end
context "when the log has a duplicate log reference" do context "when the log has a duplicate log reference" do

26
spec/services/exports/lettings_log_export_service_spec.rb

@ -256,6 +256,32 @@ RSpec.describe Exports::LettingsLogExportService do
export_service.export_xml_lettings_logs(collection_year: 2022) export_service.export_xml_lettings_logs(collection_year: 2022)
end end
context "and previous full exports are different for previous years" do
let(:expected_zip_filename) { "core_2021_2022_apr_mar_f0007_inc0004.zip" }
let(:expected_zip_filename2) { "core_2022_2023_apr_mar_f0001_inc0001.zip" }
before do
LogsExport.new(started_at: Time.zone.yesterday, base_number: 7, increment_number: 3, collection: 2021).save!
end
it "generates multiple ZIP export files with different base numbers in the filenames" do
expect(storage_service).to receive(:write_file).with(expected_zip_filename, any_args)
expect(storage_service).to receive(:write_file).with(expected_zip_filename2, any_args)
expect(Rails.logger).to receive(:info).with("Building export run for 2021")
expect(Rails.logger).to receive(:info).with("Creating core_2021_2022_apr_mar_f0007_inc0004 - 1 logs")
expect(Rails.logger).to receive(:info).with("Added core_2021_2022_apr_mar_f0007_inc0004_pt001.xml")
expect(Rails.logger).to receive(:info).with("Writing core_2021_2022_apr_mar_f0007_inc0004.zip")
expect(Rails.logger).to receive(:info).with("Building export run for 2022")
expect(Rails.logger).to receive(:info).with("Creating core_2022_2023_apr_mar_f0001_inc0001 - 1 logs")
expect(Rails.logger).to receive(:info).with("Added core_2022_2023_apr_mar_f0001_inc0001_pt001.xml")
expect(Rails.logger).to receive(:info).with("Writing core_2022_2023_apr_mar_f0001_inc0001.zip")
expect(Rails.logger).to receive(:info).with("Building export run for 2023")
expect(Rails.logger).to receive(:info).with("Creating core_2023_2024_apr_mar_f0001_inc0001 - 0 logs")
export_service.export_xml_lettings_logs
end
end
end end
end end

Loading…
Cancel
Save