Browse Source

Merge branch 'main' into CLDC-4178-add-gender-same-as-sex-question-for-sales

pull/3188/head
Nat Dean-Lewis 1 month ago
parent
commit
6a2621b8ce
  1. 20
      app/components/create_log_actions_component.html.erb
  2. 17
      app/components/create_log_actions_component.rb
  3. 28
      app/controllers/test_data_controller.rb
  4. 35
      app/helpers/bulk_upload/lettings_log_to_csv.rb
  5. 9
      app/helpers/collection_time_helper.rb
  6. 9
      app/helpers/form_page_helper.rb
  7. 2
      app/models/derived_variables/lettings_log_variables.rb
  8. 1
      app/models/form/lettings/questions/gender_same_as_sex.rb
  9. 13
      app/models/form/lettings/questions/tenancy_start_date.rb
  10. 4
      app/models/form/lettings/subsections/household_characteristics.rb
  11. 13
      app/models/form/question.rb
  12. 6
      app/models/lettings_log.rb
  13. 2
      app/models/validations/soft_validations.rb
  14. 2
      app/services/bulk_upload/lettings/year2026/csv_parser.rb
  15. 251
      app/services/bulk_upload/lettings/year2026/row_parser.rb
  16. 17
      app/services/exports/lettings_log_export_constants.rb
  17. 2
      app/services/feature_toggle.rb
  18. 2
      app/views/form/_date_question.html.erb
  19. 3
      config/locales/forms/2026/lettings/setup.en.yml
  20. 4
      config/routes.rb
  21. 8
      spec/fixtures/exports/general_needs_log_26_27.xml
  22. 6
      spec/fixtures/files/lettings_log_csv_export_codes_26.csv
  23. 6
      spec/fixtures/files/lettings_log_csv_export_labels_26.csv
  24. 6
      spec/fixtures/files/lettings_log_csv_export_non_support_codes_26.csv
  25. 6
      spec/fixtures/files/lettings_log_csv_export_non_support_labels_26.csv
  26. 16
      spec/models/form/lettings/questions/gender_same_as_sex_spec.rb
  27. 8
      spec/models/form/lettings/subsections/household_characteristics_spec.rb
  28. 4
      spec/services/bulk_upload/lettings/validator_spec.rb
  29. 8
      spec/services/bulk_upload/lettings/year2026/csv_parser_spec.rb
  30. 244
      spec/services/bulk_upload/lettings/year2026/row_parser_spec.rb
  31. 3
      spec/services/csv/lettings_log_csv_service_spec.rb
  32. 18
      spec/services/exports/lettings_log_export_service_spec.rb

20
app/components/create_log_actions_component.html.erb

@ -14,17 +14,33 @@
<span class="govuk-body govuk-body-s">These tools can only be seen and used in testing environments.</span>
<div>
<%= govuk_button_link_to create_test_log_href, class: "govuk-button" do %>
New test log
New <%= current_collection_year_label %> test log
<svg class="govuk-button__start-icon" xmlns="http://www.w3.org/2000/svg" width="17.5" height="19" viewBox="0 0 33 40" aria-hidden="true" focusable="false">
<path fill="currentColor" d="M0 0h13l20 20-20 20H0l20-20z"></path>
</svg>
<% end %>
<% if FeatureToggle.allow_future_form_use? %>
<%= govuk_button_link_to create_next_year_test_log_href, class: "govuk-button" do %>
New <%= next_collection_year_label %> test log
<svg class="govuk-button__start-icon" xmlns="http://www.w3.org/2000/svg" width="17.5" height="19" viewBox="0 0 33 40" aria-hidden="true" focusable="false">
<path fill="currentColor" d="M0 0h13l20 20-20 20H0l20-20z"></path>
</svg>
<% end %>
<% end %>
<%= govuk_button_link_to create_setup_test_log_href, class: "govuk-button" do %>
New test log (setup only)
New <%= current_collection_year_label %> test log (setup only)
<svg class="govuk-button__start-icon" xmlns="http://www.w3.org/2000/svg" width="17.5" height="19" viewBox="0 0 33 40" aria-hidden="true" focusable="false">
<path fill="currentColor" d="M0 0h13l20 20-20 20H0l20-20z"></path>
</svg>
<% end %>
<% if FeatureToggle.allow_future_form_use? %>
<%= govuk_button_link_to create_next_year_setup_test_log_href, class: "govuk-button" do %>
New <%= next_collection_year_label %> test log (setup only)
<svg class="govuk-button__start-icon" xmlns="http://www.w3.org/2000/svg" width="17.5" height="19" viewBox="0 0 33 40" aria-hidden="true" focusable="false">
<path fill="currentColor" d="M0 0h13l20 20-20 20H0l20-20z"></path>
</svg>
<% end %>
<% end %>
<%= govuk_button_link_to create_test_bulk_upload_href(2025), class: "govuk-button govuk-button--secondary" do %>
25/26 BU test file
<svg class="govuk-button__start-icon bi bi-download" xmlns="http://www.w3.org/2000/svg" width="18" height="19" fill="currentColor" viewBox="0 0 16 16" stroke="currentColor" stroke-width="1.4">

17
app/components/create_log_actions_component.rb

@ -1,5 +1,6 @@
class CreateLogActionsComponent < ViewComponent::Base
include Rails.application.routes.url_helpers
include CollectionTimeHelper
attr_reader :bulk_upload, :user, :log_type
@ -38,10 +39,26 @@ class CreateLogActionsComponent < ViewComponent::Base
send("create_test_#{log_type}_log_path")
end
def create_next_year_test_log_href
send("create_next_year_test_#{log_type}_log_path")
end
def create_setup_test_log_href
send("create_setup_test_#{log_type}_log_path")
end
def create_next_year_setup_test_log_href
send("create_next_year_setup_test_#{log_type}_log_path")
end
def current_collection_year_label
"#{current_collection_start_year - 2000}/#{current_collection_end_year - 2000}"
end
def next_collection_year_label
"#{next_collection_start_year - 2000}/#{next_collection_end_year - 2000}"
end
def create_test_bulk_upload_href(year)
send("create_#{year}_test_#{log_type}_bulk_upload_path")
end

28
app/controllers/test_data_controller.rb

@ -10,6 +10,13 @@ class TestDataController < ApplicationController
redirect_to lettings_log_path(log)
end
def create_next_year_test_lettings_log
return render_not_found unless FeatureToggle.create_test_logs_enabled?
log = FactoryBot.create(:lettings_log, :completed, assigned_to: current_user, ppostcode_full: "SW1A 1AA", manual_address_entry_selected: false, startdate: generate_different_date_within_collection_year(Time.zone.local(next_collection_start_year, 4, 1)))
redirect_to lettings_log_path(log)
end
def create_setup_test_lettings_log
return render_not_found unless FeatureToggle.create_test_logs_enabled?
@ -17,6 +24,13 @@ class TestDataController < ApplicationController
redirect_to lettings_log_path(log)
end
def create_next_year_setup_test_lettings_log
return render_not_found unless FeatureToggle.create_test_logs_enabled?
log = FactoryBot.create(:lettings_log, :setup_completed, assigned_to: current_user, manual_address_entry_selected: false, startdate: generate_different_date_within_collection_year(Time.zone.local(next_collection_start_year, 4, 1)))
redirect_to lettings_log_path(log)
end
%w[2025 2026].each do |year|
define_method("create_#{year}_test_lettings_bulk_upload") do
return render_not_found unless FeatureToggle.create_test_logs_enabled?
@ -47,6 +61,13 @@ class TestDataController < ApplicationController
redirect_to sales_log_path(log)
end
def create_next_year_test_sales_log
return render_not_found unless FeatureToggle.create_test_logs_enabled?
log = FactoryBot.create(:sales_log, :completed, assigned_to: current_user, manual_address_entry_selected: false, saledate: generate_different_date_within_collection_year(Time.zone.local(next_collection_start_year, 4, 1)))
redirect_to sales_log_path(log)
end
def create_setup_test_sales_log
return render_not_found unless FeatureToggle.create_test_logs_enabled?
@ -54,6 +75,13 @@ class TestDataController < ApplicationController
redirect_to sales_log_path(log)
end
def create_next_year_setup_test_sales_log
return render_not_found unless FeatureToggle.create_test_logs_enabled?
log = FactoryBot.create(:sales_log, :shared_ownership_setup_complete, assigned_to: current_user, manual_address_entry_selected: false, saledate: generate_different_date_within_collection_year(Time.zone.local(next_collection_start_year, 4, 1)))
redirect_to sales_log_path(log)
end
%w[2025 2026].each do |year|
define_method("create_#{year}_test_sales_bulk_upload") do
return render_not_found unless FeatureToggle.create_test_logs_enabled?

35
app/helpers/bulk_upload/lettings_log_to_csv.rb

@ -144,40 +144,40 @@ class BulkUpload::LettingsLogToCsv
log.tenancylength,
log.age1 || overrides[:age1],
log.sex1,
log.sexrab1,
log.ethnic,
log.nationality_all_group,
log.ecstat1,
relat_number(log.relat2),
log.age2 || overrides[:age2],
log.sex2,
log.sexrab2,
log.ecstat2, # 50
relat_number(log.relat3),
log.age3 || overrides[:age3],
log.sex3,
log.sexrab3,
log.ecstat3,
relat_number(log.relat4),
log.age4 || overrides[:age4],
log.sex4,
log.sexrab4,
log.ecstat4,
relat_number(log.relat5),
log.age5 || overrides[:age5], # 60
log.sex5,
log.sexrab5,
log.ecstat5,
relat_number(log.relat6),
log.age6 || overrides[:age6],
log.sex6,
log.sexrab6,
log.ecstat6,
relat_number(log.relat7),
log.age7 || overrides[:age7],
log.sex7,
log.sexrab7,
log.ecstat7, # 70
relat_number(log.relat8),
log.age8 || overrides[:age8],
log.sex8,
log.sexrab8,
log.ecstat8,
log.armedforces,
log.leftreg,
@ -239,18 +239,10 @@ class BulkUpload::LettingsLogToCsv
log.supcharg,
log.hbrentshortfall,
log.tshortfall,
log.gender_same_as_sex1, # 130
log.sexrab1, # 130
log.sexrab2,
log.sexrab3,
log.sexrab4,
log.sexrab5,
log.sexrab6,
log.sexrab7,
log.sexrab8,
log.gender_same_as_sex1,
log.gender_description1,
log.gender_same_as_sex2, # 140
log.gender_same_as_sex2,
log.gender_description2,
log.gender_same_as_sex3,
log.gender_description3,
@ -258,15 +250,16 @@ class BulkUpload::LettingsLogToCsv
log.gender_description4,
log.gender_same_as_sex5,
log.gender_description5,
log.gender_same_as_sex6,
log.gender_same_as_sex6, # 140
log.gender_description6,
log.gender_same_as_sex7, # 150
log.gender_same_as_sex7,
log.gender_description7,
log.gender_same_as_sex8,
log.gender_description8,
log.owning_organisation.prp? ? log.referral_register : nil,
log.referral_noms,
log.referral_org, # 156
log.referral_org, # 148
]
end

9
app/helpers/collection_time_helper.rb

@ -16,10 +16,13 @@ module CollectionTimeHelper
Time.zone.local(collection_start_year_for_date(date), 4, 1)
end
def date_mid_collection_year_formatted(date)
def date_mid_collection_year(date)
relevant_year = date.nil? ? current_collection_start_year : collection_start_year_for_date(date)
example_date = Date.new(relevant_year, 9, 13)
example_date.to_formatted_s(:govuk_date_number_month)
Date.new(relevant_year, 9, 13)
end
def date_mid_collection_year_formatted(date)
date_mid_collection_year(date).to_formatted_s(:govuk_date_number_month)
end
def current_collection_start_date

9
app/helpers/form_page_helper.rb

@ -1,4 +1,6 @@
module FormPageHelper
include CollectionTimeHelper
def action_href(log, page_id, referrer = "check_answers")
send("#{log.log_type}_#{page_id}_path", log, referrer:)
end
@ -46,4 +48,11 @@ module FormPageHelper
page.skip_href(log) || send(log.form.next_page_redirect_path(page, log, current_user, ignore_answered: true), log)
end
end
def date_hint(question, log)
[
question.hint_text.presence,
question.date_example_override(log) || "For example, #{date_mid_collection_year_formatted(log.startdate).tr(' ', '/')}",
].compact.join("<br><br>").html_safe
end
end

2
app/models/derived_variables/lettings_log_variables.rb

@ -300,7 +300,7 @@ private
end
def get_refused
return 1 if details_unknown? || age_refused? || sex_refused? || relat_refused? || ecstat_refused?
return 1 if details_unknown? || age_refused? || sex_refused? || sexrab_refused? || relat_refused? || ecstat_refused?
0
end

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

@ -7,6 +7,7 @@ class Form::Lettings::Questions::GenderSameAsSex < ::Form::Question
@conditional_for = { "gender_description#{person_index}" => [2] }
@person_index = person_index
@question_number = question_number
@inferred_check_answers_value = [{ "condition" => { "gender_same_as_sex#{person_index}" => 2 }, "value" => "No" }]
end
def answer_options

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

@ -1,4 +1,6 @@
class Form::Lettings::Questions::TenancyStartDate < ::Form::Question
include CollectionTimeHelper
def initialize(id, hsh, page)
super
@id = "startdate"
@ -7,5 +9,16 @@ class Form::Lettings::Questions::TenancyStartDate < ::Form::Question
@question_number = QUESTION_NUMBER_FROM_YEAR[form.start_date.year] || QUESTION_NUMBER_FROM_YEAR[QUESTION_NUMBER_FROM_YEAR.keys.max] if form.start_date.present?
end
def date_example_override(log)
return unless form.start_year_2026_or_later?
example_date =
[date_mid_collection_year(log.startdate), Time.zone.today + 7]
.min
.to_formatted_s(:govuk_date_number_month)
.tr(" ", "/")
I18n.t("forms.#{form.start_date.year}.#{copy_key}.example", default: "", example_date:)
end
QUESTION_NUMBER_FROM_YEAR = { 2023 => 5, 2024 => 7 }.freeze
end

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

@ -21,7 +21,7 @@ class Form::Lettings::Subsections::HouseholdCharacteristics < ::Form::Subsection
Form::Lettings::Pages::LeadTenantOverRetirementValueCheck.new("age_lead_tenant_over_retirement_value_check", nil, self),
(Form::Lettings::Pages::LeadTenantSexRegisteredAtBirth.new(nil, nil, self) if form.start_year_2026_or_later?),
(Form::Lettings::Pages::LeadTenantGenderSameAsSex.new(nil, nil, self) if form.start_year_2026_or_later?),
Form::Lettings::Pages::LeadTenantGenderIdentity.new(nil, nil, self),
(Form::Lettings::Pages::LeadTenantGenderIdentity.new(nil, nil, self) unless form.start_year_2026_or_later?),
(Form::Lettings::Pages::NoFemalesPregnantHouseholdLeadValueCheck.new(nil, nil, self) unless form.start_year_2026_or_later?),
(Form::Lettings::Pages::FemalesInSoftAgeRangeInPregnantHouseholdLeadValueCheck.new(nil, nil, self) unless form.start_year_2026_or_later?),
(Form::Lettings::Pages::NoHouseholdMemberLikelyToBePregnantCheck.new("no_household_member_likely_to_be_pregnant_lead_check", nil, self, person_index: 1) if form.start_year_2026_or_later?),
@ -63,7 +63,7 @@ class Form::Lettings::Subsections::HouseholdCharacteristics < ::Form::Subsection
(Form::Lettings::Pages::PartnerUnder16ValueCheck.new("age_#{person_index}_partner_under_16_value_check", nil, self, person_index:) if form.start_year_2024_or_later? && !form.start_year_2026_or_later?),
(Form::Lettings::Pages::PersonSexRegisteredAtBirth.new(nil, nil, self, person_index:) if form.start_year_2026_or_later?),
(Form::Lettings::Pages::PersonGenderSameAsSex.new(nil, nil, self, person_index:) if form.start_year_2026_or_later?),
Form::Lettings::Pages::PersonGenderIdentity.new(nil, nil, self, person_index:),
(Form::Lettings::Pages::PersonGenderIdentity.new(nil, nil, self, person_index:) unless form.start_year_2026_or_later?),
(Form::Lettings::Pages::NoFemalesPregnantHouseholdPersonValueCheck.new(nil, nil, self, person_index:) unless form.start_year_2026_or_later?),
(Form::Lettings::Pages::FemalesInSoftAgeRangeInPregnantHouseholdPersonValueCheck.new(nil, nil, self, person_index:) unless form.start_year_2026_or_later?),
(Form::Lettings::Pages::NoHouseholdMemberLikelyToBePregnantCheck.new("no_household_member_likely_to_be_pregnant_person_#{person_index}_check", nil, self, person_index:) if form.start_year_2026_or_later?),

13
app/models/form/question.rb

@ -299,6 +299,11 @@ class Form::Question
answer_options.keys.reject { |x| x.match(/divider/) }
end
# used by date questions that need bespoke formatting for the example date
def date_example_override(_log)
nil
end
private
def selected_answer_option_is_derived?(log)
@ -441,6 +446,14 @@ private
sex6: %w[R],
sex7: %w[R],
sex8: %w[R],
sexrab1: %w[R],
sexrab2: %w[R],
sexrab3: %w[R],
sexrab4: %w[R],
sexrab5: %w[R],
sexrab6: %w[R],
sexrab7: %w[R],
sexrab8: %w[R],
relat2: [3],
relat3: [3],
relat4: [3],

6
app/models/lettings_log.rb

@ -687,7 +687,7 @@ class LettingsLog < Log
end
def has_any_person_details?(person_index)
["sex#{person_index}", "relat#{person_index}", "ecstat#{person_index}"].any? { |field| public_send(field).present? } || public_send("age#{person_index}_known") == 1
["sex#{person_index}", "sexrab#{person_index}", "relat#{person_index}", "ecstat#{person_index}"].any? { |field| public_send(field).present? } || public_send("age#{person_index}_known") == 1
end
def details_not_known_for_person?(person_index)
@ -911,6 +911,10 @@ private
[sex1, sex2, sex3, sex4, sex5, sex6, sex7, sex8].any?("R")
end
def sexrab_refused?
[sexrab1, sexrab2, sexrab3, sexrab4, sexrab5, sexrab6, sexrab7, sexrab8].any?("R")
end
def relat_refused?
[relat2, relat3, relat4, relat5, relat6, relat7, relat8].any?("R")
end

2
app/models/validations/soft_validations.rb

@ -329,6 +329,8 @@ private
end
def at_least_one_person_working_situation_is_illness?
return if hhmemb.present? && hhmemb > 8
person_count = hhmemb || 8
(1..person_count).any? { |n| public_send("ecstat#{n}") == 8 }

2
app/services/bulk_upload/lettings/year2026/csv_parser.rb

@ -4,7 +4,7 @@ class BulkUpload::Lettings::Year2026::CsvParser
include CollectionTimeHelper
# TODO: CLDC-4162: Update when 2026 format is known
FIELDS = 156
FIELDS = 148
FORM_YEAR = 2026
attr_reader :path

251
app/services/bulk_upload/lettings/year2026/row_parser.rb

@ -47,37 +47,37 @@ class BulkUpload::Lettings::Year2026::RowParser
field_40: "If 'Other', what is the type of tenancy?",
field_41: "What is the length of the fixed-term tenancy to the nearest year?",
field_42: "What is the lead tenant’s age?",
field_43: "Which of these best describes the lead tenant’s gender identity?",
field_43: "Lead tenant's sex, as registered at birth",
field_44: "Which of these best describes the lead tenant’s ethnic background?",
field_45: "What is the lead tenant’s nationality?",
field_46: "Which of these best describes the lead tenant’s working situation?",
field_47: "Is person 2 the partner of the lead tenant?",
field_48: "What is person 2’s age?",
field_49: "Which of these best describes person 2’s gender identity?",
field_49: "Person 2's sex, as registered at birth",
field_50: "Which of these best describes person 2’s working situation?",
field_51: "Is person 3 the partner of the lead tenant?",
field_52: "What is person 3’s age?",
field_53: "Which of these best describes person 3’s gender identity?",
field_53: "Person 3's sex, as registered at birth",
field_54: "Which of these best describes person 3’s working situation?",
field_55: "Is person 4 the partner of the lead tenant?",
field_56: "What is person 4’s age?",
field_57: "Which of these best describes person 4’s gender identity?",
field_57: "Person 4's sex, as registered at birth",
field_58: "Which of these best describes person 4’s working situation?",
field_59: "Is person 5 the partner of the lead tenant?",
field_60: "What is person 5’s age?",
field_61: "Which of these best describes person 5’s gender identity?",
field_61: "Person 5's sex, as registered at birth",
field_62: "Which of these best describes person 5’s working situation?",
field_63: "Is person 6 the partner of the lead tenant?",
field_64: "What is person 6’s age?",
field_65: "Which of these best describes person 6’s gender identity?",
field_65: "Person 6's sex, as registered at birth",
field_66: "Which of these best describes person 6’s working situation?",
field_67: "Is person 7 the partner of the lead tenant?",
field_68: "What is person 7’s age?",
field_69: "Which of these best describes person 7’s gender identity?",
field_69: "Person 7's sex, as registered at birth",
field_70: "Which of these best describes person 7’s working situation?",
field_71: "Is person 8 the partner of the lead tenant?",
field_72: "What is person 8’s age?",
field_73: "Which of these best describes person 8’s gender identity?",
field_73: "Person 8's sex, as registered at birth",
field_74: "Which of these best describes person 8’s working situation?",
field_75: "Does anybody in the household have links to the UK armed forces?",
field_76: "Is this person still serving in the UK armed forces?",
@ -135,34 +135,26 @@ class BulkUpload::Lettings::Year2026::RowParser
field_128: "After the household has received any housing-related benefits, will they still need to pay for rent and charges?",
field_129: "What do you expect the outstanding amount to be?",
field_130: "Lead tenant's sex, as registered at birth",
field_131: "Person 2's sex, as registered at birth",
field_132: "Person 3's sex, as registered at birth",
field_133: "Person 4's sex, as registered at birth",
field_134: "Person 5's sex, as registered at birth",
field_135: "Person 6's sex, as registered at birth",
field_136: "Person 7's sex, as registered at birth",
field_137: "Person 8's sex, as registered at birth",
field_138: "Is the gender the lead tenant identifies with the same as their sex registered at birth?",
field_139: "If 'No', enter the lead tenant's gender identity",
field_140: "Is the gender person 2 identifies with the same as their sex registered at birth?",
field_141: "If 'No', enter person 2's gender identity",
field_142: "Is the gender person 3 identifies with the same as their sex registered at birth?",
field_143: "If 'No', enter person 3's gender identity",
field_144: "Is the gender person 4 identifies with the same as their sex registered at birth?",
field_145: "If 'No', enter person 4's gender identity",
field_146: "Is the gender person 5 identifies with the same as their sex registered at birth?",
field_147: "If 'No', enter person 5's gender identity",
field_148: "Is the gender person 6 identifies with the same as their sex registered at birth?",
field_149: "If 'No', enter person 6's gender identity",
field_150: "Is the gender person 7 identifies with the same as their sex registered at birth?",
field_151: "If 'No', enter person 7's gender identity",
field_152: "Is the gender person 8 identifies with the same as their sex registered at birth?",
field_153: "If 'No', enter person 8's gender identity",
field_154: "What was the source of referral for this letting? - PRP properties part 1",
field_155: "What was the source of referral for this letting? - PRP properties part 2",
field_156: "What was the source of referral for this letting? - PRP properties part 3",
field_130: "Is the gender the lead tenant identifies with the same as their sex registered at birth?",
field_131: "If 'No', enter the lead tenant's gender identity",
field_132: "Is the gender person 2 identifies with the same as their sex registered at birth?",
field_133: "If 'No', enter person 2's gender identity",
field_134: "Is the gender person 3 identifies with the same as their sex registered at birth?",
field_135: "If 'No', enter person 3's gender identity",
field_136: "Is the gender person 4 identifies with the same as their sex registered at birth?",
field_137: "If 'No', enter person 4's gender identity",
field_138: "Is the gender person 5 identifies with the same as their sex registered at birth?",
field_139: "If 'No', enter person 5's gender identity",
field_140: "Is the gender person 6 identifies with the same as their sex registered at birth?",
field_141: "If 'No', enter person 6's gender identity",
field_142: "Is the gender person 7 identifies with the same as their sex registered at birth?",
field_143: "If 'No', enter person 7's gender identity",
field_144: "Is the gender person 8 identifies with the same as their sex registered at birth?",
field_145: "If 'No', enter person 8's gender identity",
field_146: "What was the source of referral for this letting? - PRP properties part 1",
field_147: "What was the source of referral for this letting? - PRP properties part 2",
field_148: "What was the source of referral for this letting? - PRP properties part 3",
}.freeze
RENT_TYPE_BU_MAPPING = {
@ -312,13 +304,13 @@ class BulkUpload::Lettings::Year2026::RowParser
attribute :field_128, :integer
attribute :field_129, :decimal
attribute :field_130, :string
attribute :field_130, :integer
attribute :field_131, :string
attribute :field_132, :string
attribute :field_132, :integer
attribute :field_133, :string
attribute :field_134, :string
attribute :field_134, :integer
attribute :field_135, :string
attribute :field_136, :string
attribute :field_136, :integer
attribute :field_137, :string
attribute :field_138, :integer
attribute :field_139, :string
@ -328,18 +320,10 @@ class BulkUpload::Lettings::Year2026::RowParser
attribute :field_143, :string
attribute :field_144, :integer
attribute :field_145, :string
attribute :field_146, :integer
attribute :field_147, :string
attribute :field_147, :integer
attribute :field_148, :integer
attribute :field_149, :string
attribute :field_150, :integer
attribute :field_151, :string
attribute :field_152, :integer
attribute :field_153, :string
attribute :field_154, :integer
attribute :field_155, :integer
attribute :field_156, :integer
validate :validate_valid_radio_option, on: :before_log
@ -597,8 +581,7 @@ class BulkUpload::Lettings::Year2026::RowParser
!supported_housing? ? "field_23" : nil, # postcode # TODO: CLDC-4119: add postcode to hash for supported housing
!supported_housing? ? "field_24" : nil, # postcode # TODO: CLDC-4119: add postcode to hash for supported housing
"field_42", # age1
"field_43", # sex1
"field_130", # sexrab1
"field_43", # sexrab1
"field_46", # ecstat1
)
if [field_124, field_125, field_126, field_127].all?(&:present?)
@ -748,7 +731,6 @@ private
"startdate",
"age1",
"sexrab1",
"sex1",
"ecstat1",
"owning_organisation",
"tcharge",
@ -1030,8 +1012,7 @@ private
errors.add(:field_24, error_message) unless supported_housing? # postcode_full # TODO: CLDC-4119: add postcode to error fields for supported housing
errors.add(:field_25, error_message) unless supported_housing? # la # TODO: CLDC-4119: add LA to error fields for supported housing
errors.add(:field_42, error_message) # age1
errors.add(:field_130, error_message) # sexrab1
errors.add(:field_43, error_message) # sex1
errors.add(:field_43, error_message) # sexrab1
errors.add(:field_46, error_message) # ecstat1
errors.add(:field_122, error_message) unless general_needs? # household_charge
errors.add(:field_124, error_message) # brent
@ -1051,31 +1032,31 @@ private
def field_referral_register_prp_valid?
if owning_organisation&.prp?
[5, 6, 7, 8, 9].include?(field_154)
[5, 6, 7, 8, 9].include?(field_146)
else
field_154.blank?
field_146.blank?
end
end
def field_referral_noms_valid?
case field_154
case field_146
when 6
[1, 2, 3, 4].include?(field_155)
[1, 2, 3, 4].include?(field_147)
when 7
[5, 6, 7, 8].include?(field_155)
[5, 6, 7, 8].include?(field_147)
else
field_155.blank?
field_147.blank?
end
end
def field_referral_org_valid?
case field_155
case field_147
when 1
[1, 2, 3, 4, 5, 6, 7, 8, 9, 10].include?(field_156)
[1, 2, 3, 4, 5, 6, 7, 8, 9, 10].include?(field_148)
when 7
[11, 12, 13, 14, 15, 16, 17, 18, 19, 20].include?(field_156)
[11, 12, 13, 14, 15, 16, 17, 18, 19, 20].include?(field_148)
else
field_156.blank?
field_148.blank?
end
end
@ -1087,7 +1068,7 @@ private
return if renewal?
return if referral_fields_valid?
%i[field_116 field_154 field_155 field_156].each do |field|
%i[field_116 field_146 field_147 field_148].each do |field|
errors.add(field, I18n.t("#{ERROR_BASE_KEY}.referral.invalid_option"))
end
end
@ -1140,14 +1121,14 @@ private
age8_known: %i[field_72],
age8: %i[field_72],
sex1: %i[field_43],
sex2: %i[field_49],
sex3: %i[field_53],
sex4: %i[field_57],
sex5: %i[field_61],
sex6: %i[field_65],
sex7: %i[field_69],
sex8: %i[field_73],
sexrab1: %i[field_43],
sexrab2: %i[field_49],
sexrab3: %i[field_53],
sexrab4: %i[field_57],
sexrab5: %i[field_61],
sexrab6: %i[field_65],
sexrab7: %i[field_69],
sexrab8: %i[field_73],
ethnic_group: %i[field_44],
ethnic: %i[field_44],
@ -1204,9 +1185,9 @@ private
accessible_register: %i[field_115],
letting_allocation: %i[field_112 field_113 field_114 field_115],
referral_register: %i[field_116 field_154],
referral_noms: %i[field_155],
referral_org: %i[field_156],
referral_register: %i[field_116 field_146],
referral_noms: %i[field_147],
referral_org: %i[field_148],
net_income_known: %i[field_117],
incfreq: %i[field_118],
@ -1255,30 +1236,22 @@ private
county: [:field_22],
uprn_selection: [:field_19],
sexrab1: %i[field_130],
sexrab2: %i[field_131],
sexrab3: %i[field_132],
sexrab4: %i[field_133],
sexrab5: %i[field_134],
sexrab6: %i[field_135],
sexrab7: %i[field_136],
sexrab8: %i[field_137],
gender_same_as_sex1: %i[field_138],
gender_same_as_sex2: %i[field_140],
gender_same_as_sex3: %i[field_142],
gender_same_as_sex4: %i[field_144],
gender_same_as_sex5: %i[field_146],
gender_same_as_sex6: %i[field_148],
gender_same_as_sex7: %i[field_150],
gender_same_as_sex8: %i[field_152],
gender_description1: %i[field_139],
gender_description2: %i[field_141],
gender_description3: %i[field_143],
gender_description4: %i[field_145],
gender_description5: %i[field_147],
gender_description6: %i[field_149],
gender_description7: %i[field_151],
gender_description8: %i[field_153],
gender_same_as_sex1: %i[field_130],
gender_same_as_sex2: %i[field_132],
gender_same_as_sex3: %i[field_134],
gender_same_as_sex4: %i[field_136],
gender_same_as_sex5: %i[field_138],
gender_same_as_sex6: %i[field_140],
gender_same_as_sex7: %i[field_142],
gender_same_as_sex8: %i[field_144],
gender_description1: %i[field_131],
gender_description2: %i[field_133],
gender_description3: %i[field_135],
gender_description4: %i[field_137],
gender_description5: %i[field_139],
gender_description6: %i[field_141],
gender_description7: %i[field_143],
gender_description8: %i[field_145],
}.compact
end
@ -1340,14 +1313,14 @@ private
attributes["age8_known"] = age8_known?
attributes["age8"] = field_72 if attributes["age8_known"]&.zero? && field_72&.match(/\A\d{1,3}\z|\AR\z/)
attributes["sex1"] = field_43
attributes["sex2"] = field_49
attributes["sex3"] = field_53
attributes["sex4"] = field_57
attributes["sex5"] = field_61
attributes["sex6"] = field_65
attributes["sex7"] = field_69
attributes["sex8"] = field_73
attributes["sexrab1"] = field_43
attributes["sexrab2"] = field_49
attributes["sexrab3"] = field_53
attributes["sexrab4"] = field_57
attributes["sexrab5"] = field_61
attributes["sexrab6"] = field_65
attributes["sexrab7"] = field_69
attributes["sexrab8"] = field_73
attributes["ethnic_group"] = ethnic_group_from_ethnic
attributes["ethnic"] = field_44
@ -1486,30 +1459,22 @@ private
attributes["postcode_full_input"] = postcode_full
attributes["select_best_address_match"] = true if field_18.blank?
attributes["sexrab1"] = field_130
attributes["sexrab2"] = field_131
attributes["sexrab3"] = field_132
attributes["sexrab4"] = field_133
attributes["sexrab5"] = field_134
attributes["sexrab6"] = field_135
attributes["sexrab7"] = field_136
attributes["sexrab8"] = field_137
attributes["gender_same_as_sex1"] = field_138
attributes["gender_description1"] = field_139
attributes["gender_same_as_sex2"] = field_140
attributes["gender_description2"] = field_141
attributes["gender_same_as_sex3"] = field_142
attributes["gender_description3"] = field_143
attributes["gender_same_as_sex4"] = field_144
attributes["gender_description4"] = field_145
attributes["gender_same_as_sex5"] = field_146
attributes["gender_description5"] = field_147
attributes["gender_same_as_sex6"] = field_148
attributes["gender_description6"] = field_149
attributes["gender_same_as_sex7"] = field_150
attributes["gender_description7"] = field_151
attributes["gender_same_as_sex8"] = field_152
attributes["gender_description8"] = field_153
attributes["gender_same_as_sex1"] = field_130
attributes["gender_description1"] = field_131
attributes["gender_same_as_sex2"] = field_132
attributes["gender_description2"] = field_133
attributes["gender_same_as_sex3"] = field_134
attributes["gender_description3"] = field_135
attributes["gender_same_as_sex4"] = field_136
attributes["gender_description4"] = field_137
attributes["gender_same_as_sex5"] = field_138
attributes["gender_description5"] = field_139
attributes["gender_same_as_sex6"] = field_140
attributes["gender_description6"] = field_141
attributes["gender_same_as_sex7"] = field_142
attributes["gender_description7"] = field_143
attributes["gender_same_as_sex8"] = field_144
attributes["gender_description8"] = field_145
attributes
end
@ -1617,31 +1582,31 @@ private
end
def person_2_present?
field_47.present? || field_48.present? || field_49.present? || field_131.present? || field_140.present? || field_141.present?
field_47.present? || field_48.present? || field_49.present? || field_132.present? || field_133.present?
end
def person_3_present?
field_51.present? || field_52.present? || field_53.present? || field_132.present? || field_142.present? || field_143.present?
field_51.present? || field_52.present? || field_53.present? || field_134.present? || field_135.present?
end
def person_4_present?
field_55.present? || field_56.present? || field_57.present? || field_133.present? || field_144.present? || field_145.present?
field_55.present? || field_56.present? || field_57.present? || field_136.present? || field_137.present?
end
def person_5_present?
field_59.present? || field_60.present? || field_61.present? || field_134.present? || field_146.present? || field_147.present?
field_59.present? || field_60.present? || field_61.present? || field_138.present? || field_139.present?
end
def person_6_present?
field_63.present? || field_64.present? || field_65.present? || field_135.present? || field_148.present? || field_149.present?
field_63.present? || field_64.present? || field_65.present? || field_140.present? || field_141.present?
end
def person_7_present?
field_67.present? || field_68.present? || field_69.present? || field_136.present? || field_150.present? || field_151.present?
field_67.present? || field_68.present? || field_69.present? || field_142.present? || field_143.present?
end
def person_8_present?
field_71.present? || field_72.present? || field_73.present? || field_137.present? || field_152.present? || field_153.present?
field_71.present? || field_72.present? || field_73.present? || field_144.present? || field_145.present?
end
def leftreg
@ -1847,7 +1812,7 @@ private
if owning_organisation.la?
field_116
else
field_154
field_146
end
end
@ -1856,7 +1821,7 @@ private
return unless referral_fields_valid?
if owning_organisation.prp?
field_155
field_147
end
end
@ -1865,7 +1830,7 @@ private
return unless referral_fields_valid?
if owning_organisation.prp?
field_156
field_148
end
end
end

17
app/services/exports/lettings_log_export_constants.rb

@ -140,7 +140,6 @@ module Exports::LettingsLogExportConstants
(1..8).each do |index|
ALL_YEAR_EXPORT_FIELDS << "age#{index}"
ALL_YEAR_EXPORT_FIELDS << "ecstat#{index}"
ALL_YEAR_EXPORT_FIELDS << "sex#{index}"
end
(2..8).each do |index|
ALL_YEAR_EXPORT_FIELDS << "relat#{index}"
@ -159,6 +158,9 @@ module Exports::LettingsLogExportConstants
"offered",
"referral",
]
(1..8).each do |index|
YEAR_2021_EXPORT_FIELDS << "sex#{index}"
end
YEAR_2022_EXPORT_FIELDS = Set[
"builtype",
@ -167,6 +169,9 @@ module Exports::LettingsLogExportConstants
"offered",
"referral",
]
(1..8).each do |index|
YEAR_2022_EXPORT_FIELDS << "sex#{index}"
end
YEAR_2023_EXPORT_FIELDS = Set[
"builtype",
@ -175,6 +180,9 @@ module Exports::LettingsLogExportConstants
"offered",
"referral",
]
(1..8).each do |index|
YEAR_2023_EXPORT_FIELDS << "sex#{index}"
end
YEAR_2024_EXPORT_FIELDS = Set[
"builtype",
@ -196,6 +204,9 @@ module Exports::LettingsLogExportConstants
"carehome_charges_value_check",
"referral",
]
(1..8).each do |index|
YEAR_2024_EXPORT_FIELDS << "sex#{index}"
end
YEAR_2025_EXPORT_FIELDS = Set[
"builtype",
@ -215,6 +226,9 @@ module Exports::LettingsLogExportConstants
"supcharg_value_check",
"referral",
]
(1..8).each do |index|
YEAR_2025_EXPORT_FIELDS << "sex#{index}"
end
YEAR_2026_EXPORT_FIELDS = Set[
"accessible_register",
@ -235,7 +249,6 @@ module Exports::LettingsLogExportConstants
"referral_noms",
"referral_org",
]
(1..8).each do |index|
YEAR_2026_EXPORT_FIELDS << "sexrab#{index}"
YEAR_2026_EXPORT_FIELDS << "gender_same_as_sex#{index}"

2
app/services/feature_toggle.rb

@ -28,7 +28,7 @@ class FeatureToggle
end
def self.create_test_logs_enabled?
Rails.env.development? || Rails.env.review?
Rails.env.development? || Rails.env.review? || Rails.env.staging?
end
def self.sales_export_enabled?

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

@ -6,7 +6,7 @@
question_id: question.id,
legend: { text: legend[:text], size: legend[:size], caption: caption(caption_text, page_header, conditional) },
resource_type: @log.log_type,
hint: (question.hint_text.blank? ? "" : (question.hint_text.html_safe + "</br></br>".html_safe)) + "For example, #{date_mid_collection_year_formatted(@log.startdate).tr(' ', '/')}",
hint: date_hint(question, @log),
f:,
} %>

3
config/locales/forms/2026/lettings/setup.en.yml

@ -63,7 +63,8 @@ en:
page_header: ""
check_answer_label: "Tenancy start date"
check_answer_prompt: ""
hint_text: ""
hint_text: "The tenancy start date can be up to 14 days from today. If your tenancy starts more than 14 days into the future, please wait until you are within 14 days of the start date before submitting your log. <br><br>For example, if you’re answering this question on 1 April, you can enter a tenancy start date up to and including 15 April."
example: "Enter the date in the format DD/MM/YYYY, for example %{example_date}."
question_text: "What is the tenancy start date?"
rent_type:

4
config/routes.rb

@ -405,11 +405,15 @@ Rails.application.routes.draw do
if FeatureToggle.create_test_logs_enabled?
get "create-test-lettings-log", to: "test_data#create_test_lettings_log"
get "create-next-year-test-lettings-log", to: "test_data#create_next_year_test_lettings_log"
get "create-setup-test-lettings-log", to: "test_data#create_setup_test_lettings_log"
get "create-next-year-setup-test-lettings-log", to: "test_data#create_next_year_setup_test_lettings_log"
get "create-2025-test-lettings-bulk-upload", to: "test_data#create_2025_test_lettings_bulk_upload"
get "create-2026-test-lettings-bulk-upload", to: "test_data#create_2026_test_lettings_bulk_upload"
get "create-test-sales-log", to: "test_data#create_test_sales_log"
get "create-next-year-test-sales-log", to: "test_data#create_next_year_test_sales_log"
get "create-setup-test-sales-log", to: "test_data#create_setup_test_sales_log"
get "create-next-year-setup-test-sales-log", to: "test_data#create_next_year_setup_test_sales_log"
get "create-2025-test-sales-bulk-upload", to: "test_data#create_2025_test_sales_bulk_upload"
get "create-2026-test-sales-bulk-upload", to: "test_data#create_2026_test_sales_bulk_upload"
end

8
spec/fixtures/exports/general_needs_log_26_27.xml vendored

@ -5,7 +5,6 @@
<tenancycode>BZ737</tenancycode>
<age1>35</age1>
<sexrab1>F</sexrab1>
<sex1>F</sex1>
<gender_same_as_sex1>1</gender_same_as_sex1>
<gender_description1/>
<ethnic>2</ethnic>
@ -14,43 +13,36 @@
<hhmemb>2</hhmemb>
<age2>32</age2>
<sexrab2>M</sexrab2>
<sex2>M</sex2>
<gender_same_as_sex2>2</gender_same_as_sex2>
<gender_description2>Non-binary</gender_description2>
<ecstat2>6</ecstat2>
<age3/>
<sexrab3/>
<sex3/>
<gender_same_as_sex3/>
<gender_description3/>
<ecstat3/>
<age4/>
<sexrab4/>
<sex4/>
<gender_same_as_sex4/>
<gender_description4/>
<ecstat4/>
<age5/>
<sexrab5/>
<sex5/>
<gender_same_as_sex5/>
<gender_description5/>
<ecstat5/>
<age6/>
<sexrab6/>
<sex6/>
<gender_same_as_sex6/>
<gender_description6/>
<ecstat6/>
<age7/>
<sexrab7/>
<sex7/>
<gender_same_as_sex7/>
<gender_description7/>
<ecstat7/>
<age8/>
<sexrab8/>
<sex8/>
<gender_same_as_sex8/>
<gender_description8/>
<ecstat8/>

6
spec/fixtures/files/lettings_log_csv_export_codes_26.csv vendored

File diff suppressed because one or more lines are too long

6
spec/fixtures/files/lettings_log_csv_export_labels_26.csv vendored

File diff suppressed because one or more lines are too long

6
spec/fixtures/files/lettings_log_csv_export_non_support_codes_26.csv vendored

File diff suppressed because one or more lines are too long

6
spec/fixtures/files/lettings_log_csv_export_non_support_labels_26.csv vendored

File diff suppressed because one or more lines are too long

16
spec/models/form/lettings/questions/gender_same_as_sex_spec.rb

@ -42,7 +42,7 @@ RSpec.describe Form::Lettings::Questions::GenderSameAsSex, type: :model do
end
it "has the correct inferred_check_answers_value" do
expect(question.inferred_check_answers_value).to be_nil
expect(question.inferred_check_answers_value).to eq([{ "condition" => { "gender_same_as_sex#{person_index}" => 2 }, "value" => "No" }])
end
it "has the correct question number" do
@ -72,7 +72,7 @@ RSpec.describe Form::Lettings::Questions::GenderSameAsSex, type: :model do
end
it "has the correct inferred_check_answers_value" do
expect(question.inferred_check_answers_value).to be_nil
expect(question.inferred_check_answers_value).to eq([{ "condition" => { "gender_same_as_sex#{person_index}" => 2 }, "value" => "No" }])
end
it "has the correct question number" do
@ -102,7 +102,7 @@ RSpec.describe Form::Lettings::Questions::GenderSameAsSex, type: :model do
end
it "has the correct inferred_check_answers_value" do
expect(question.inferred_check_answers_value).to be_nil
expect(question.inferred_check_answers_value).to eq([{ "condition" => { "gender_same_as_sex#{person_index}" => 2 }, "value" => "No" }])
end
it "has the correct question number" do
@ -132,7 +132,7 @@ RSpec.describe Form::Lettings::Questions::GenderSameAsSex, type: :model do
end
it "has the correct inferred_check_answers_value" do
expect(question.inferred_check_answers_value).to be_nil
expect(question.inferred_check_answers_value).to eq([{ "condition" => { "gender_same_as_sex#{person_index}" => 2 }, "value" => "No" }])
end
it "has the correct question number" do
@ -162,7 +162,7 @@ RSpec.describe Form::Lettings::Questions::GenderSameAsSex, type: :model do
end
it "has the correct inferred_check_answers_value" do
expect(question.inferred_check_answers_value).to be_nil
expect(question.inferred_check_answers_value).to eq([{ "condition" => { "gender_same_as_sex#{person_index}" => 2 }, "value" => "No" }])
end
it "has the correct question number" do
@ -192,7 +192,7 @@ RSpec.describe Form::Lettings::Questions::GenderSameAsSex, type: :model do
end
it "has the correct inferred_check_answers_value" do
expect(question.inferred_check_answers_value).to be_nil
expect(question.inferred_check_answers_value).to eq([{ "condition" => { "gender_same_as_sex#{person_index}" => 2 }, "value" => "No" }])
end
it "has the correct question number" do
@ -222,7 +222,7 @@ RSpec.describe Form::Lettings::Questions::GenderSameAsSex, type: :model do
end
it "has the correct inferred_check_answers_value" do
expect(question.inferred_check_answers_value).to be_nil
expect(question.inferred_check_answers_value).to eq([{ "condition" => { "gender_same_as_sex#{person_index}" => 2 }, "value" => "No" }])
end
it "has the correct question number" do
@ -252,7 +252,7 @@ RSpec.describe Form::Lettings::Questions::GenderSameAsSex, type: :model do
end
it "has the correct inferred_check_answers_value" do
expect(question.inferred_check_answers_value).to be_nil
expect(question.inferred_check_answers_value).to eq([{ "condition" => { "gender_same_as_sex#{person_index}" => 2 }, "value" => "No" }])
end
it "has the correct question number" do

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

@ -346,7 +346,6 @@ RSpec.describe Form::Lettings::Subsections::HouseholdCharacteristics, type: :mod
age_lead_tenant_over_retirement_value_check
lead_tenant_sex_registered_at_birth
lead_tenant_gender_same_as_sex
lead_tenant_gender_identity
no_household_member_likely_to_be_pregnant_lead_check
gender_lead_tenant_over_retirement_value_check
lead_tenant_ethnic_group
@ -369,7 +368,6 @@ RSpec.describe Form::Lettings::Subsections::HouseholdCharacteristics, type: :mod
age_2_over_retirement_value_check
person_2_sex_registered_at_birth
person_2_gender_same_as_sex
person_2_gender_identity
no_household_member_likely_to_be_pregnant_person_2_check
gender_2_over_retirement_value_check
person_2_working_situation
@ -385,7 +383,6 @@ RSpec.describe Form::Lettings::Subsections::HouseholdCharacteristics, type: :mod
age_3_over_retirement_value_check
person_3_sex_registered_at_birth
person_3_gender_same_as_sex
person_3_gender_identity
no_household_member_likely_to_be_pregnant_person_3_check
gender_3_over_retirement_value_check
person_3_working_situation
@ -401,7 +398,6 @@ RSpec.describe Form::Lettings::Subsections::HouseholdCharacteristics, type: :mod
age_4_over_retirement_value_check
person_4_sex_registered_at_birth
person_4_gender_same_as_sex
person_4_gender_identity
no_household_member_likely_to_be_pregnant_person_4_check
gender_4_over_retirement_value_check
person_4_working_situation
@ -417,7 +413,6 @@ RSpec.describe Form::Lettings::Subsections::HouseholdCharacteristics, type: :mod
age_5_over_retirement_value_check
person_5_sex_registered_at_birth
person_5_gender_same_as_sex
person_5_gender_identity
no_household_member_likely_to_be_pregnant_person_5_check
gender_5_over_retirement_value_check
person_5_working_situation
@ -433,7 +428,6 @@ RSpec.describe Form::Lettings::Subsections::HouseholdCharacteristics, type: :mod
age_6_over_retirement_value_check
person_6_sex_registered_at_birth
person_6_gender_same_as_sex
person_6_gender_identity
no_household_member_likely_to_be_pregnant_person_6_check
gender_6_over_retirement_value_check
person_6_working_situation
@ -449,7 +443,6 @@ RSpec.describe Form::Lettings::Subsections::HouseholdCharacteristics, type: :mod
age_7_over_retirement_value_check
person_7_sex_registered_at_birth
person_7_gender_same_as_sex
person_7_gender_identity
no_household_member_likely_to_be_pregnant_person_7_check
gender_7_over_retirement_value_check
person_7_working_situation
@ -465,7 +458,6 @@ RSpec.describe Form::Lettings::Subsections::HouseholdCharacteristics, type: :mod
age_8_over_retirement_value_check
person_8_sex_registered_at_birth
person_8_gender_same_as_sex
person_8_gender_identity
no_household_member_likely_to_be_pregnant_person_8_check
gender_8_over_retirement_value_check
person_8_working_situation

4
spec/services/bulk_upload/lettings/validator_spec.rb

@ -190,8 +190,8 @@ RSpec.describe BulkUpload::Lettings::Validator do
expect(error.tenant_code).to eql(log.tenancycode)
expect(error.property_ref).to eql(log.propcode)
expect(error.row).to eql("2")
expect(error.cell).to eql("EH2") # this may change when adding a new field as the cols are in a random order
expect(error.col).to eql("EH") # this may change when adding a new field as the cols are in a random order
expect(error.cell).to eql("EB2") # this may change when adding a new field as the cols are in a random order
expect(error.col).to eql("EB") # this may change when adding a new field as the cols are in a random order
end
end
end

8
spec/services/bulk_upload/lettings/year2026/csv_parser_spec.rb

@ -244,10 +244,10 @@ RSpec.describe BulkUpload::Lettings::Year2026::CsvParser do
end
it "returns correct column" do
expect(service.column_for_field("field_5")).to eql("AI")
expect(service.column_for_field("field_22")).to eql("BR")
expect(service.column_for_field("field_26")).to eql("CG")
expect(service.column_for_field("field_25")).to eql("E")
expect(service.column_for_field("field_5")).to eql("AA")
expect(service.column_for_field("field_22")).to eql("BK")
expect(service.column_for_field("field_26")).to eql("BZ")
expect(service.column_for_field("field_25")).to eql("S")
end
end
end

244
spec/services/bulk_upload/lettings/year2026/row_parser_spec.rb

@ -249,30 +249,22 @@ RSpec.describe BulkUpload::Lettings::Year2026::RowParser do
field_18: "12",
field_130: "F",
field_131: "M",
field_132: "R",
field_133: "F",
field_134: "M",
field_135: "R",
field_136: "F",
field_137: "M",
field_138: "1",
field_139: "",
field_140: "2",
field_141: "identity",
field_142: "3",
field_130: "1",
field_131: "",
field_132: "2",
field_133: "identity",
field_134: "3",
field_135: "",
field_136: "1",
field_137: "",
field_138: "2",
field_139: "identity",
field_140: "3",
field_141: "",
field_142: "1",
field_143: "",
field_144: "1",
field_145: "",
field_146: "2",
field_147: "identity",
field_148: "3",
field_149: "",
field_150: "1",
field_151: "",
field_152: "2",
field_153: "identity",
field_144: "2",
field_145: "identity",
}
end
@ -323,7 +315,7 @@ RSpec.describe BulkUpload::Lettings::Year2026::RowParser do
:field_24, # postcode_full
:field_25, # LA
:field_42, # age1
:field_43, # sex1
:field_43, # sexrab1
:field_46, # ecstat1
:field_124, # brent
:field_125, # scharge
@ -377,7 +369,7 @@ RSpec.describe BulkUpload::Lettings::Year2026::RowParser do
:field_13, # tenancycode
:field_6, # location
:field_42, # age1
:field_43, # sex1
:field_43, # sexrab1
:field_46, # ecstat1
:field_124, # brent
:field_125, # scharge
@ -419,7 +411,7 @@ RSpec.describe BulkUpload::Lettings::Year2026::RowParser do
:field_13, # tenancycode
:field_6, # location
:field_42, # age1
:field_43, # sex1
:field_43, # sexrab1
:field_46, # ecstat1
:field_124, # brent
:field_125, # scharge
@ -462,7 +454,7 @@ RSpec.describe BulkUpload::Lettings::Year2026::RowParser do
:field_13, # tenancycode
:field_6, # location
:field_42, # age1
:field_43, # sex1
:field_43, # sexrab1
:field_46, # ecstat1
].each do |field|
expect(parser.errors[field]).to include(error_message)
@ -508,7 +500,7 @@ RSpec.describe BulkUpload::Lettings::Year2026::RowParser do
:field_13, # tenancycode
:field_6, # location
:field_42, # age1
:field_43, # sex1
:field_43, # sexrab1
:field_46, # ecstat1
:field_122, # household_charge
].each do |field|
@ -562,7 +554,7 @@ RSpec.describe BulkUpload::Lettings::Year2026::RowParser do
:field_24, # postcode_full
:field_25, # LA
:field_42, # age1
:field_43, # sex1
:field_43, # sexrab1
:field_46, # ecstat1
].each do |field|
expect(parser.errors[field]).to be_blank
@ -634,7 +626,7 @@ RSpec.describe BulkUpload::Lettings::Year2026::RowParser do
it "fetches the question's check_answer_label if it exists" do
parser.valid?
expect(parser.errors[:field_43]).to eql([I18n.t("validations.lettings.2026.bulk_upload.not_answered", question: "lead tenant’s gender identity.")])
expect(parser.errors[:field_43]).to eql([I18n.t("validations.lettings.2026.bulk_upload.not_answered", question: "lead tenant’s sex registered at birth.")])
end
end
@ -1160,7 +1152,7 @@ RSpec.describe BulkUpload::Lettings::Year2026::RowParser do
end
end
describe "#field_116, field_154, field_155, field_156" do # referral
describe "#field_116, field_146, field_147, field_148" do # referral
context "when org is LA" do
let(:owning_org) { create(:organisation, :la, :with_old_visible_id) }
@ -1175,9 +1167,9 @@ RSpec.describe BulkUpload::Lettings::Year2026::RowParser do
it "does not add an error" do
parser.valid?
expect(parser.errors[:field_116]).to be_blank
expect(parser.errors[:field_154]).to be_blank
expect(parser.errors[:field_155]).to be_blank
expect(parser.errors[:field_156]).to be_blank
expect(parser.errors[:field_146]).to be_blank
expect(parser.errors[:field_147]).to be_blank
expect(parser.errors[:field_148]).to be_blank
end
end
@ -1187,9 +1179,9 @@ RSpec.describe BulkUpload::Lettings::Year2026::RowParser do
it "adds errors to all referral fields" do
parser.valid?
expect(parser.errors[:field_116]).to be_present
expect(parser.errors[:field_154]).to be_present
expect(parser.errors[:field_155]).to be_present
expect(parser.errors[:field_156]).to be_present
expect(parser.errors[:field_146]).to be_present
expect(parser.errors[:field_147]).to be_present
expect(parser.errors[:field_148]).to be_present
end
end
@ -1199,34 +1191,34 @@ RSpec.describe BulkUpload::Lettings::Year2026::RowParser do
it "adds errors to all referral fields" do
parser.valid?
expect(parser.errors[:field_116]).to be_present
expect(parser.errors[:field_154]).to be_present
expect(parser.errors[:field_155]).to be_present
expect(parser.errors[:field_156]).to be_present
expect(parser.errors[:field_146]).to be_present
expect(parser.errors[:field_147]).to be_present
expect(parser.errors[:field_148]).to be_present
end
end
context "and other fields are given" do
let(:attributes) { renewal_attributes.merge({ field_116: 1, field_154: 5, field_155: 1, field_152: 1 }) }
let(:attributes) { renewal_attributes.merge({ field_116: 1, field_146: 5, field_147: 1, field_144: 1 }) }
it "adds errors to all referral fields" do
parser.valid?
expect(parser.errors[:field_116]).to be_present
expect(parser.errors[:field_154]).to be_present
expect(parser.errors[:field_155]).to be_present
expect(parser.errors[:field_156]).to be_present
expect(parser.errors[:field_146]).to be_present
expect(parser.errors[:field_147]).to be_present
expect(parser.errors[:field_148]).to be_present
end
end
end
context "and is renewal" do
let(:attributes) { org_attributes.merge({ field_7: 1, field_116: 1, field_154: 5, field_155: 1, field_156: 1 }) }
let(:attributes) { org_attributes.merge({ field_7: 1, field_116: 1, field_146: 5, field_147: 1, field_148: 1 }) }
it "does not add an error for referral fields" do
parser.valid?
expect(parser.errors[:field_116]).to be_blank
expect(parser.errors[:field_154]).to be_blank
expect(parser.errors[:field_155]).to be_blank
expect(parser.errors[:field_156]).to be_blank
expect(parser.errors[:field_146]).to be_blank
expect(parser.errors[:field_147]).to be_blank
expect(parser.errors[:field_148]).to be_blank
end
end
end
@ -1239,141 +1231,141 @@ RSpec.describe BulkUpload::Lettings::Year2026::RowParser do
context "and not renewal" do
let(:renewal_attributes) { org_attributes.merge({ field_7: nil }) }
context "and field_154 is valid and does not expect an answer for field_155" do
let(:attributes) { renewal_attributes.merge({ field_154: 5 }) }
context "and field_146 is valid and does not expect an answer for field_147" do
let(:attributes) { renewal_attributes.merge({ field_146: 5 }) }
it "does not add an error" do
parser.valid?
expect(parser.errors[:field_116]).to be_blank
expect(parser.errors[:field_154]).to be_blank
expect(parser.errors[:field_155]).to be_blank
expect(parser.errors[:field_156]).to be_blank
expect(parser.errors[:field_146]).to be_blank
expect(parser.errors[:field_147]).to be_blank
expect(parser.errors[:field_148]).to be_blank
end
context "and later fields are given" do
let(:attributes) { renewal_attributes.merge({ field_154: 5, field_155: 1, field_156: 1 }) }
let(:attributes) { renewal_attributes.merge({ field_146: 5, field_147: 1, field_148: 1 }) }
it "adds errors to all referral fields" do
parser.valid?
expect(parser.errors[:field_116]).to be_present
expect(parser.errors[:field_154]).to be_present
expect(parser.errors[:field_155]).to be_present
expect(parser.errors[:field_156]).to be_present
expect(parser.errors[:field_146]).to be_present
expect(parser.errors[:field_147]).to be_present
expect(parser.errors[:field_148]).to be_present
end
end
end
context "and field_154 is invalid" do
let(:attributes) { renewal_attributes.merge({ field_154: 1 }) } # LA option
context "and field_146 is invalid" do
let(:attributes) { renewal_attributes.merge({ field_146: 1 }) } # LA option
it "adds errors to all referral fields" do
parser.valid?
expect(parser.errors[:field_116]).to be_present
expect(parser.errors[:field_154]).to be_present
expect(parser.errors[:field_155]).to be_present
expect(parser.errors[:field_156]).to be_present
expect(parser.errors[:field_146]).to be_present
expect(parser.errors[:field_147]).to be_present
expect(parser.errors[:field_148]).to be_present
end
end
context "and field_154 is blank" do
let(:attributes) { renewal_attributes.merge({ field_154: nil }) }
context "and field_146 is blank" do
let(:attributes) { renewal_attributes.merge({ field_146: nil }) }
it "adds errors to all referral fields" do
parser.valid?
expect(parser.errors[:field_116]).to be_present
expect(parser.errors[:field_154]).to be_present
expect(parser.errors[:field_155]).to be_present
expect(parser.errors[:field_156]).to be_present
expect(parser.errors[:field_146]).to be_present
expect(parser.errors[:field_147]).to be_present
expect(parser.errors[:field_148]).to be_present
end
end
context "and field_154 is valid and expects an answer for field_155" do
let(:field_154_attributes) { renewal_attributes.merge({ field_154: 6 }) }
context "and field_146 is valid and expects an answer for field_147" do
let(:field_146_attributes) { renewal_attributes.merge({ field_146: 6 }) }
context "and field_155 is valid and does not expect an answer for field_156" do
let(:attributes) { field_154_attributes.merge({ field_155: 2 }) }
context "and field_147 is valid and does not expect an answer for field_148" do
let(:attributes) { field_146_attributes.merge({ field_147: 2 }) }
it "does not add an error" do
parser.valid?
expect(parser.errors[:field_116]).to be_blank
expect(parser.errors[:field_154]).to be_blank
expect(parser.errors[:field_155]).to be_blank
expect(parser.errors[:field_156]).to be_blank
expect(parser.errors[:field_146]).to be_blank
expect(parser.errors[:field_147]).to be_blank
expect(parser.errors[:field_148]).to be_blank
end
context "and later fields are given" do
let(:attributes) { field_154_attributes.merge({ field_155: 2, field_156: 1 }) }
let(:attributes) { field_146_attributes.merge({ field_147: 2, field_148: 1 }) }
it "adds errors to all referral fields" do
parser.valid?
expect(parser.errors[:field_116]).to be_present
expect(parser.errors[:field_154]).to be_present
expect(parser.errors[:field_155]).to be_present
expect(parser.errors[:field_156]).to be_present
expect(parser.errors[:field_146]).to be_present
expect(parser.errors[:field_147]).to be_present
expect(parser.errors[:field_148]).to be_present
end
end
end
context "and field_155 is invalid" do
let(:attributes) { field_154_attributes.merge({ field_155: 5 }) } # needs field_154 to be 7
context "and field_147 is invalid" do
let(:attributes) { field_146_attributes.merge({ field_147: 5 }) } # needs field_146 to be 7
it "adds errors to all referral fields" do
parser.valid?
expect(parser.errors[:field_116]).to be_present
expect(parser.errors[:field_154]).to be_present
expect(parser.errors[:field_155]).to be_present
expect(parser.errors[:field_156]).to be_present
expect(parser.errors[:field_146]).to be_present
expect(parser.errors[:field_147]).to be_present
expect(parser.errors[:field_148]).to be_present
end
end
context "and field_155 is blank" do
let(:attributes) { field_154_attributes.merge({ field_155: nil }) }
context "and field_147 is blank" do
let(:attributes) { field_146_attributes.merge({ field_147: nil }) }
it "adds errors to all referral fields" do
parser.valid?
expect(parser.errors[:field_116]).to be_present
expect(parser.errors[:field_154]).to be_present
expect(parser.errors[:field_155]).to be_present
expect(parser.errors[:field_156]).to be_present
expect(parser.errors[:field_146]).to be_present
expect(parser.errors[:field_147]).to be_present
expect(parser.errors[:field_148]).to be_present
end
end
context "and field_155 is valid and expects an answer for field_156" do
let(:field_155_attributes) { field_154_attributes.merge({ field_155: 1 }) }
context "and field_147 is valid and expects an answer for field_148" do
let(:field_147_attributes) { field_146_attributes.merge({ field_147: 1 }) }
context "and field_156 is valid" do
let(:attributes) { field_155_attributes.merge({ field_156: 1 }) }
context "and field_148 is valid" do
let(:attributes) { field_147_attributes.merge({ field_148: 1 }) }
it "does not add an error" do
parser.valid?
expect(parser.errors[:field_116]).to be_blank
expect(parser.errors[:field_154]).to be_blank
expect(parser.errors[:field_155]).to be_blank
expect(parser.errors[:field_156]).to be_blank
expect(parser.errors[:field_146]).to be_blank
expect(parser.errors[:field_147]).to be_blank
expect(parser.errors[:field_148]).to be_blank
end
end
context "and field_156 is invalid" do
let(:attributes) { field_155_attributes.merge({ field_156: 11 }) } # needs field_155 to be 7
context "and field_148 is invalid" do
let(:attributes) { field_147_attributes.merge({ field_148: 11 }) } # needs field_147 to be 7
it "adds errors to all referral fields" do
parser.valid?
expect(parser.errors[:field_116]).to be_present
expect(parser.errors[:field_154]).to be_present
expect(parser.errors[:field_155]).to be_present
expect(parser.errors[:field_156]).to be_present
expect(parser.errors[:field_146]).to be_present
expect(parser.errors[:field_147]).to be_present
expect(parser.errors[:field_148]).to be_present
end
end
context "and field_156 is blank" do
let(:attributes) { field_155_attributes.merge({ field_156: nil }) }
context "and field_148 is blank" do
let(:attributes) { field_147_attributes.merge({ field_148: nil }) }
it "adds errors to all referral fields" do
parser.valid?
expect(parser.errors[:field_116]).to be_present
expect(parser.errors[:field_154]).to be_present
expect(parser.errors[:field_155]).to be_present
expect(parser.errors[:field_156]).to be_present
expect(parser.errors[:field_146]).to be_present
expect(parser.errors[:field_147]).to be_present
expect(parser.errors[:field_148]).to be_present
end
end
end
@ -1381,14 +1373,14 @@ RSpec.describe BulkUpload::Lettings::Year2026::RowParser do
end
context "and is renewal" do
let(:attributes) { org_attributes.merge({ field_7: 1, field_116: 1, field_154: 5, field_155: 1, field_156: 1 }) }
let(:attributes) { org_attributes.merge({ field_7: 1, field_116: 1, field_146: 5, field_147: 1, field_148: 1 }) }
it "does not add an error for referral fields" do
parser.valid?
expect(parser.errors[:field_116]).to be_blank
expect(parser.errors[:field_154]).to be_blank
expect(parser.errors[:field_155]).to be_blank
expect(parser.errors[:field_156]).to be_blank
expect(parser.errors[:field_146]).to be_blank
expect(parser.errors[:field_147]).to be_blank
expect(parser.errors[:field_148]).to be_blank
end
end
end
@ -2084,22 +2076,22 @@ RSpec.describe BulkUpload::Lettings::Year2026::RowParser do
end
context "when a soft validation is triggered that relates both to fields that are and are not routed to" do
let(:attributes) { setup_section_params.merge({ field_78: "1", field_130: "M", field_131: "M", field_132: "M", field_138: 1, field_140: 1, field_142: 1 }) }
let(:attributes) { setup_section_params.merge({ field_78: "1", field_43: "M", field_49: "M", field_53: "M", field_130: 1, field_132: 1, field_134: 1 }) }
it "adds errors to fields that are routed to" do
parser.valid?
expect(parser.errors.where(:field_43, category: :soft_validation)).to be_present
expect(parser.errors.where(:field_130, category: :soft_validation)).to be_present
expect(parser.errors.where(:field_138, category: :soft_validation)).to be_present
expect(parser.errors.where(:field_131, category: :soft_validation)).to be_present
expect(parser.errors.where(:field_140, category: :soft_validation)).to be_present
expect(parser.errors.where(:field_49, category: :soft_validation)).to be_present
expect(parser.errors.where(:field_132, category: :soft_validation)).to be_present
end
it "does not add errors to fields that are not routed to" do
parser.valid?
expect(parser.errors.where(:field_133, category: :soft_validation)).not_to be_present
expect(parser.errors.where(:field_144, category: :soft_validation)).not_to be_present
expect(parser.errors.where(:field_134, category: :soft_validation)).not_to be_present
expect(parser.errors.where(:field_146, category: :soft_validation)).not_to be_present
expect(parser.errors.where(:field_57, category: :soft_validation)).not_to be_present
expect(parser.errors.where(:field_136, category: :soft_validation)).not_to be_present
expect(parser.errors.where(:field_61, category: :soft_validation)).not_to be_present
expect(parser.errors.where(:field_138, category: :soft_validation)).not_to be_present
end
end
@ -2501,7 +2493,7 @@ RSpec.describe BulkUpload::Lettings::Year2026::RowParser do
end
end
describe "#sexN fields" do
describe "#sexrabN fields" do
let(:attributes) do
{
bulk_upload:,
@ -2517,14 +2509,14 @@ RSpec.describe BulkUpload::Lettings::Year2026::RowParser do
end
it "sets value from correct mapping" do
expect(parser.log.sex1).to eql("F")
expect(parser.log.sex2).to eql("M")
expect(parser.log.sex3).to eql("X")
expect(parser.log.sex4).to eql("R")
expect(parser.log.sex5).to eql("F")
expect(parser.log.sex6).to eql("M")
expect(parser.log.sex7).to eql("X")
expect(parser.log.sex8).to eql("R")
expect(parser.log.sexrab1).to eql("F")
expect(parser.log.sexrab2).to eql("M")
expect(parser.log.sexrab3).to eql("X")
expect(parser.log.sexrab4).to eql("R")
expect(parser.log.sexrab5).to eql("F")
expect(parser.log.sexrab6).to eql("M")
expect(parser.log.sexrab7).to eql("X")
expect(parser.log.sexrab8).to eql("R")
end
end

3
spec/services/csv/lettings_log_csv_service_spec.rb

@ -241,7 +241,6 @@ RSpec.describe Csv::LettingsLogCsvService do
hhmemb: 4,
age1_known: 0,
age1: 35,
sex1: "F",
sexrab1: "F",
gender_same_as_sex1: 1,
ethnic_group: 0,
@ -252,7 +251,6 @@ RSpec.describe Csv::LettingsLogCsvService do
relat2: "P",
age2_known: 0,
age2: 32,
sex2: "M",
sexrab2: "M",
gender_same_as_sex2: 2,
gender_description2: "Non-binary",
@ -261,7 +259,6 @@ RSpec.describe Csv::LettingsLogCsvService do
details_known_4: 0,
relat4: "R",
age4_known: 1,
sex4: "R",
sexrab4: "R",
gender_same_as_sex4: 3,
ecstat4: 10,

18
spec/services/exports/lettings_log_export_service_spec.rb

@ -83,7 +83,7 @@ RSpec.describe Exports::LettingsLogExportService do
end
context "and one lettings log is available for export" do
let!(:lettings_log) { FactoryBot.create(:lettings_log, :completed, assigned_to: user, age1: 35, sex1: "F", age2: 32, sex2: "M", propcode: "123", ppostcode_full: "SE2 6RT", postcode_full: "NW1 5TY", town_or_city: "London", tenancycode: "BZ737", startdate: Time.zone.local(2022, 2, 2, 10, 36, 49), voiddate: Time.zone.local(2019, 11, 3), mrcdate: Time.zone.local(2020, 5, 5, 10, 36, 49), tenancylength: 5, underoccupation_benefitcap: 4) }
let!(:lettings_log) { FactoryBot.create(:lettings_log, :completed, assigned_to: user, age1: 35, sex1: "F", sexrab1: nil, age2: 32, sex2: "M", sexrab2: nil, propcode: "123", ppostcode_full: "SE2 6RT", postcode_full: "NW1 5TY", town_or_city: "London", tenancycode: "BZ737", startdate: Time.zone.local(2022, 2, 2, 10, 36, 49), voiddate: Time.zone.local(2019, 11, 3), mrcdate: Time.zone.local(2020, 5, 5, 10, 36, 49), tenancylength: 5, underoccupation_benefitcap: 4) }
it "generates a ZIP export file with the expected filename" do
expect(storage_service).to receive(:write_file).with(expected_zip_filename, any_args)
@ -127,7 +127,7 @@ RSpec.describe Exports::LettingsLogExportService do
end
context "and one lettings log with unknown user details is available for export" do
let!(:lettings_log) { FactoryBot.create(:lettings_log, :completed, details_known_2: 1, assigned_to: user, age1: 35, sex1: "F", propcode: "123", ppostcode_full: "SE2 6RT", postcode_full: "NW1 5TY", town_or_city: "London", tenancycode: "BZ737", startdate: Time.zone.local(2022, 2, 2, 10, 36, 49), voiddate: Time.zone.local(2019, 11, 3), mrcdate: Time.zone.local(2020, 5, 5, 10, 36, 49), tenancylength: 5, underoccupation_benefitcap: 4) }
let!(:lettings_log) { FactoryBot.create(:lettings_log, :completed, details_known_2: 1, assigned_to: user, age1: 35, sex1: "F", sexrab1: nil, propcode: "123", ppostcode_full: "SE2 6RT", postcode_full: "NW1 5TY", town_or_city: "London", tenancycode: "BZ737", startdate: Time.zone.local(2022, 2, 2, 10, 36, 49), voiddate: Time.zone.local(2019, 11, 3), mrcdate: Time.zone.local(2020, 5, 5, 10, 36, 49), tenancylength: 5, underoccupation_benefitcap: 4) }
def replace_person_details(export_file)
export_file.sub!("<age2>32</age2>", "<age2>-9</age2>")
@ -180,7 +180,7 @@ RSpec.describe Exports::LettingsLogExportService do
end
context "and one lettings log is available for export" do
let!(:lettings_log) { FactoryBot.create(:lettings_log, :completed, assigned_to: user, age1: 35, sex1: "F", age2: 32, sex2: "M", uprn_known: 1, uprn: "100023336956", propcode: "123", postcode_full: "SE2 6RT", ppostcode_full: "SE2 6RT", tenancycode: "BZ737", startdate: Time.zone.local(2023, 4, 2, 10, 36, 49), voiddate: Time.zone.local(2021, 11, 3), mrcdate: Time.zone.local(2022, 5, 5, 10, 36, 49), tenancylength: 5, underoccupation_benefitcap: 4) }
let!(:lettings_log) { FactoryBot.create(:lettings_log, :completed, assigned_to: user, age1: 35, sex1: "F", sexrab1: nil, age2: 32, sex2: "M", sexrab2: nil, uprn_known: 1, uprn: "100023336956", propcode: "123", postcode_full: "SE2 6RT", ppostcode_full: "SE2 6RT", tenancycode: "BZ737", startdate: Time.zone.local(2023, 4, 2, 10, 36, 49), voiddate: Time.zone.local(2021, 11, 3), mrcdate: Time.zone.local(2022, 5, 5, 10, 36, 49), tenancylength: 5, underoccupation_benefitcap: 4) }
let(:expected_zip_filename) { "core_2023_2024_apr_mar_f0001_inc0001.zip" }
let(:expected_data_filename) { "core_2023_2024_apr_mar_f0001_inc0001_pt001.xml" }
let(:xml_export_file) { File.open("spec/fixtures/exports/general_needs_log_23_24.xml", "r:UTF-8") }
@ -400,7 +400,7 @@ RSpec.describe Exports::LettingsLogExportService do
end
context "and one lettings log with duplicate reference is available for export" do
let!(:lettings_log) { FactoryBot.create(:lettings_log, :completed, assigned_to: user, age1: 35, sex1: "F", age2: 32, sex2: "M", propcode: "123", ppostcode_full: "SE2 6RT", postcode_full: "NW1 5TY", town_or_city: "London", tenancycode: "BZ737", startdate: Time.zone.local(2022, 2, 2, 10, 36, 49), voiddate: Time.zone.local(2019, 11, 3), mrcdate: Time.zone.local(2020, 5, 5, 10, 36, 49), tenancylength: 5, underoccupation_benefitcap: 4, duplicate_set_id: 123) }
let!(:lettings_log) { FactoryBot.create(:lettings_log, :completed, assigned_to: user, age1: 35, sex1: "F", sexrab1: nil, age2: 32, sex2: "M", sexrab2: nil, propcode: "123", ppostcode_full: "SE2 6RT", postcode_full: "NW1 5TY", town_or_city: "London", tenancycode: "BZ737", startdate: Time.zone.local(2022, 2, 2, 10, 36, 49), voiddate: Time.zone.local(2019, 11, 3), mrcdate: Time.zone.local(2020, 5, 5, 10, 36, 49), tenancylength: 5, underoccupation_benefitcap: 4, duplicate_set_id: 123) }
def replace_duplicate_set_id(export_file)
export_file.sub!("<duplicate_set_id/>", "<duplicate_set_id>123</duplicate_set_id>")
@ -433,7 +433,7 @@ RSpec.describe Exports::LettingsLogExportService do
end
context "and one lettings log is available for export" do
let!(:lettings_log) { FactoryBot.create(:lettings_log, :completed, assigned_to: user, age1: 35, sex1: "F", age2: 32, sex2: "M", ppostcode_full: "A1 1AA", nationality_all_group: 13, propcode: "123", postcode_full: "SE2 6RT", tenancycode: "BZ737", startdate: Time.zone.local(2024, 4, 2, 10, 36, 49), voiddate: Time.zone.local(2021, 11, 3), mrcdate: Time.zone.local(2022, 5, 5, 10, 36, 49), tenancylength: 5, underoccupation_benefitcap: 4, creation_method: 2, bulk_upload_id: 1, address_line1_as_entered: "address line 1 as entered", address_line2_as_entered: "address line 2 as entered", town_or_city_as_entered: "town or city as entered", county_as_entered: "county as entered", postcode_full_as_entered: "AB1 2CD", la_as_entered: "la as entered", manual_address_entry_selected: false, uprn: "1", uprn_known: 1) }
let!(:lettings_log) { FactoryBot.create(:lettings_log, :completed, assigned_to: user, age1: 35, sex1: "F", sexrab1: nil, age2: 32, sex2: "M", sexrab2: nil, ppostcode_full: "A1 1AA", nationality_all_group: 13, propcode: "123", postcode_full: "SE2 6RT", tenancycode: "BZ737", startdate: Time.zone.local(2024, 4, 2, 10, 36, 49), voiddate: Time.zone.local(2021, 11, 3), mrcdate: Time.zone.local(2022, 5, 5, 10, 36, 49), tenancylength: 5, underoccupation_benefitcap: 4, creation_method: 2, bulk_upload_id: 1, address_line1_as_entered: "address line 1 as entered", address_line2_as_entered: "address line 2 as entered", town_or_city_as_entered: "town or city as entered", county_as_entered: "county as entered", postcode_full_as_entered: "AB1 2CD", la_as_entered: "la as entered", manual_address_entry_selected: false, uprn: "1", uprn_known: 1) }
let(:expected_zip_filename) { "core_2024_2025_apr_mar_f0001_inc0001.zip" }
let(:expected_data_filename) { "core_2024_2025_apr_mar_f0001_inc0001_pt001.xml" }
let(:xml_export_file) { File.open("spec/fixtures/exports/general_needs_log_24_25.xml", "r:UTF-8") }
@ -465,7 +465,7 @@ RSpec.describe Exports::LettingsLogExportService do
end
context "and one lettings log is available for export" do
let!(:lettings_log) { FactoryBot.create(:lettings_log, :completed, startdate: Time.zone.local(2025, 4, 3), assigned_to: user, age1: 35, sex1: "F", age2: 32, sex2: "M", ppostcode_full: "A1 1AA", nationality_all_group: 13, propcode: "123", postcode_full: "SE2 6RT", tenancycode: "BZ737", voiddate: Time.zone.local(2021, 11, 3), mrcdate: Time.zone.local(2022, 5, 5, 10, 36, 49), tenancylength: 5, underoccupation_benefitcap: 4, creation_method: 2, bulk_upload_id: 1, address_line1_as_entered: "address line 1 as entered", address_line2_as_entered: "address line 2 as entered", town_or_city_as_entered: "town or city as entered", county_as_entered: "county as entered", postcode_full_as_entered: "AB1 2CD", la_as_entered: "la as entered", manual_address_entry_selected: false, uprn: "1", uprn_known: 1) }
let!(:lettings_log) { FactoryBot.create(:lettings_log, :completed, startdate: Time.zone.local(2025, 4, 3), assigned_to: user, age1: 35, sex1: "F", sexrab1: nil, age2: 32, sex2: "M", sexrab2: nil, ppostcode_full: "A1 1AA", nationality_all_group: 13, propcode: "123", postcode_full: "SE2 6RT", tenancycode: "BZ737", voiddate: Time.zone.local(2021, 11, 3), mrcdate: Time.zone.local(2022, 5, 5, 10, 36, 49), tenancylength: 5, underoccupation_benefitcap: 4, creation_method: 2, bulk_upload_id: 1, address_line1_as_entered: "address line 1 as entered", address_line2_as_entered: "address line 2 as entered", town_or_city_as_entered: "town or city as entered", county_as_entered: "county as entered", postcode_full_as_entered: "AB1 2CD", la_as_entered: "la as entered", manual_address_entry_selected: false, uprn: "1", uprn_known: 1) }
let(:expected_zip_filename) { "core_2025_2026_apr_mar_f0001_inc0001.zip" }
let(:expected_data_filename) { "core_2025_2026_apr_mar_f0001_inc0001_pt001.xml" }
let(:xml_export_file) { File.open("spec/fixtures/exports/general_needs_log_25_26.xml", "r:UTF-8") }
@ -505,10 +505,10 @@ RSpec.describe Exports::LettingsLogExportService do
assigned_to: user,
age1: 35,
sexrab1: "F",
sex1: "F",
sex1: nil,
age2: 32,
sexrab2: "M",
sex2: "M",
sex2: nil,
ppostcode_full: "A1 1AA",
nationality_all_group: 13,
propcode: "123",
@ -643,7 +643,7 @@ RSpec.describe Exports::LettingsLogExportService do
let(:scheme) { FactoryBot.create(:scheme, :export, owning_organisation: organisation) }
let(:location) { FactoryBot.create(:location, :export, scheme:, startdate: Time.zone.local(2021, 4, 1), old_id: "1a") }
let(:lettings_log) { FactoryBot.create(:lettings_log, :completed, :export, :sh, scheme:, location:, assigned_to: user, updated_by: other_user, owning_organisation: organisation, age1: 35, sex1: "F", age2: 32, sex2: "M", startdate: Time.zone.local(2022, 2, 2, 10, 36, 49), voiddate: Time.zone.local(2019, 11, 3), mrcdate: Time.zone.local(2020, 5, 5, 10, 36, 49), underoccupation_benefitcap: 4, sheltered: 1) }
let(:lettings_log) { FactoryBot.create(:lettings_log, :completed, :export, :sh, scheme:, location:, assigned_to: user, updated_by: other_user, owning_organisation: organisation, age1: 35, sex1: "F", sexrab1: nil, age2: 32, sex2: "M", sexrab2: nil, startdate: Time.zone.local(2022, 2, 2, 10, 36, 49), voiddate: Time.zone.local(2019, 11, 3), mrcdate: Time.zone.local(2020, 5, 5, 10, 36, 49), underoccupation_benefitcap: 4, sheltered: 1) }
before do
lettings_log.postcode_full = nil

Loading…
Cancel
Save