Browse Source

Merge 1c6860f90b into 3df65b8998

pull/3177/merge
Nat Dean-Lewis 1 day ago committed by GitHub
parent
commit
99af487c0f
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
  1. 34
      app/helpers/bulk_upload/lettings_log_to_csv.rb
  2. 2
      app/models/derived_variables/lettings_log_variables.rb
  3. 4
      app/models/form/lettings/subsections/household_characteristics.rb
  4. 8
      app/models/form/question.rb
  5. 6
      app/models/lettings_log.rb
  6. 2
      app/services/bulk_upload/lettings/year2026/csv_parser.rb
  7. 166
      app/services/bulk_upload/lettings/year2026/row_parser.rb
  8. 17
      app/services/exports/lettings_log_export_constants.rb
  9. 8
      spec/fixtures/exports/general_needs_log_26_27.xml
  10. 6
      spec/fixtures/files/lettings_log_csv_export_codes_26.csv
  11. 6
      spec/fixtures/files/lettings_log_csv_export_labels_26.csv
  12. 6
      spec/fixtures/files/lettings_log_csv_export_non_support_codes_26.csv
  13. 6
      spec/fixtures/files/lettings_log_csv_export_non_support_labels_26.csv
  14. 8
      spec/models/form/lettings/subsections/household_characteristics_spec.rb
  15. 4
      spec/services/bulk_upload/lettings/validator_spec.rb
  16. 8
      spec/services/bulk_upload/lettings/year2026/csv_parser_spec.rb
  17. 73
      spec/services/bulk_upload/lettings/year2026/row_parser_spec.rb
  18. 3
      spec/services/csv/lettings_log_csv_service_spec.rb
  19. 18
      spec/services/exports/lettings_log_export_service_spec.rb

34
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,
@ -240,17 +240,9 @@ class BulkUpload::LettingsLogToCsv
log.hbrentshortfall,
log.tshortfall,
log.sexrab1, # 130
log.sexrab2,
log.sexrab3,
log.sexrab4,
log.sexrab5,
log.sexrab6,
log.sexrab7,
log.sexrab8,
log.gender_same_as_sex1,
log.gender_same_as_sex1, # 130
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,12 +250,12 @@ 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, # 153
log.gender_description8, # 145
]
end

2
app/models/derived_variables/lettings_log_variables.rb

@ -272,7 +272,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

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

@ -19,7 +19,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),
Form::Lettings::Pages::FemalesInSoftAgeRangeInPregnantHouseholdLeadValueCheck.new(nil, nil, self),
Form::Lettings::Pages::LeadTenantOverRetirementValueCheck.new("gender_lead_tenant_over_retirement_value_check", nil, self),
@ -59,7 +59,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:),
Form::Lettings::Pages::FemalesInSoftAgeRangeInPregnantHouseholdPersonValueCheck.new(nil, nil, self, person_index:),
Form::Lettings::Pages::PersonOverRetirementValueCheck.new("gender_#{person_index}_over_retirement_value_check", nil, self, person_index:),

8
app/models/form/question.rb

@ -434,6 +434,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

@ -676,7 +676,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)
@ -884,6 +884,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/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 = 153
FIELDS = 145
FORM_YEAR = 2026
attr_reader :path

166
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,30 +135,22 @@ 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_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",
}.freeze
RENT_TYPE_BU_MAPPING = {
@ -324,14 +316,6 @@ 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_148, :integer
attribute :field_149, :string
attribute :field_150, :integer
attribute :field_151, :string
attribute :field_152, :integer
attribute :field_153, :string
validate :validate_valid_radio_option, on: :before_log
@ -590,8 +574,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?)
@ -741,7 +724,6 @@ private
"startdate",
"age1",
"sexrab1",
"sex1",
"ecstat1",
"owning_organisation",
"tcharge",
@ -1031,8 +1013,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
@ -1090,14 +1071,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],
@ -1203,15 +1184,6 @@ private
town_or_city: [:field_21],
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],
}.compact
end
@ -1273,14 +1245,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
@ -1418,30 +1390,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
@ -1549,31 +1513,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

17
app/services/exports/lettings_log_export_constants.rb

@ -141,7 +141,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
"national",
"offered",
]
(1..8).each do |index|
YEAR_2021_EXPORT_FIELDS << "sex#{index}"
end
YEAR_2022_EXPORT_FIELDS = Set[
"builtype",
@ -166,6 +168,9 @@ module Exports::LettingsLogExportConstants
"national",
"offered",
]
(1..8).each do |index|
YEAR_2022_EXPORT_FIELDS << "sex#{index}"
end
YEAR_2023_EXPORT_FIELDS = Set[
"builtype",
@ -173,6 +178,9 @@ module Exports::LettingsLogExportConstants
"national",
"offered",
]
(1..8).each do |index|
YEAR_2023_EXPORT_FIELDS << "sex#{index}"
end
YEAR_2024_EXPORT_FIELDS = Set[
"builtype",
@ -193,6 +201,9 @@ module Exports::LettingsLogExportConstants
"supcharg_value_check",
"carehome_charges_value_check",
]
(1..8).each do |index|
YEAR_2024_EXPORT_FIELDS << "sex#{index}"
end
YEAR_2025_EXPORT_FIELDS = Set[
"builtype",
@ -211,6 +222,9 @@ module Exports::LettingsLogExportConstants
"pscharge_value_check",
"supcharg_value_check",
]
(1..8).each do |index|
YEAR_2025_EXPORT_FIELDS << "sex#{index}"
end
YEAR_2026_EXPORT_FIELDS = Set[
"accessible_register",
@ -228,7 +242,6 @@ module Exports::LettingsLogExportConstants
"pscharge_value_check",
"supcharg_value_check",
]
(1..8).each do |index|
YEAR_2026_EXPORT_FIELDS << "sexrab#{index}"
YEAR_2026_EXPORT_FIELDS << "gender_same_as_sex#{index}"

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

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

@ -348,7 +348,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_females_pregnant_household_lead_value_check
females_in_soft_age_range_in_pregnant_household_lead_value_check
gender_lead_tenant_over_retirement_value_check
@ -373,7 +372,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_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
@ -391,7 +389,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_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
@ -409,7 +406,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_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
@ -427,7 +423,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_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
@ -445,7 +440,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_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
@ -463,7 +457,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_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
@ -481,7 +474,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_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

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("EF2")
expect(error.col).to eql("EF")
expect(error.cell).to eql("DX2")
expect(error.col).to eql("DX")
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("AG")
expect(service.column_for_field("field_22")).to eql("BO")
expect(service.column_for_field("field_26")).to eql("CD")
expect(service.column_for_field("field_25")).to eql("E")
expect(service.column_for_field("field_5")).to eql("M")
expect(service.column_for_field("field_22")).to eql("BA")
expect(service.column_for_field("field_26")).to eql("BT")
expect(service.column_for_field("field_25")).to eql("C")
end
end
end

73
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
@ -1893,7 +1885,8 @@ RSpec.describe BulkUpload::Lettings::Year2026::RowParser do
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_43: "M", field_49: "M", field_53: "M" }) }
it "adds errors to fields that are routed to" do
# TODO: CLDC-4143 re-enable this test to check validation
xit "adds errors to fields that are routed to" do
parser.valid?
expect(parser.errors.where(:field_49, category: :soft_validation)).to be_present
expect(parser.errors.where(:field_53, category: :soft_validation)).to be_present
@ -2304,7 +2297,7 @@ RSpec.describe BulkUpload::Lettings::Year2026::RowParser do
end
end
describe "#sexN fields" do
describe "#sexrabN fields" do
let(:attributes) do
{
bulk_upload:,
@ -2320,14 +2313,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