Browse Source

CLDC-4140: remove old gender question lettings (#3177)

* CLDC-4141: copy person questions refactor from CLDC-4142

* CLDC-4141: remove gender same as sex and replace gender identity q

* CLDC-4141: replace sex with sexrab where relevant for 2026

* CLDC-4141: update download order

* CLDC-4140: remove sex from rowparser entirely

* CLDC-4140: keep sex in factory for now

* CLDC-4140: update household characteristics test

* CLDC-4140: update log variable spec

* CLDC-4140: update csv export tests

* CLDC-4140: update validator tests

* CLDC-4140: update row-parser spec

* CLDC-4140: update csv-parser spec

* CLDC-4140: update export spec

* CLDC-4140: update log var defs spec

* CLDC-4140: update export spec

* CLDC-4140: update row parser spec

* CLDC-4140: update validator spec

* CLDC-4140: update csv parser spec

* CLDC-4143: Update gender retirement validations

rename functions as the new wording is more related to those that identify as male and any other option

* CLDC-4143: Add 2026 tests

* CLDC-4143: Update legacy json files

causes issues with some old tests

* CLDC-4143: Add error mappings for gender fields

* CLDC-4143: Add new gender age retirement soft validation

replaces the many check pages from previous years with a single one

shows if either of the previous ones would show

has agreed wording on ticket

* fixup! CLDC-4143: Update gender retirement validations

improve gender comment wording

* CLDC-4143: Update non males validation name

reference to 'soft validation' we found confusing

* fixup! CLDC-4143: Add new gender age retirement soft validation

update subsection specs

* CLDC-4140: update parsers post merge

* CLDC-4140: update tests after field renumbering

* CLDC-4140: update tests after field renumbering

* CLDC-4140: update spacing in to_2026_row

* CLDC-4140: update row parser spec field numbers

* CLDC-4140: update row parser field types

---------

Co-authored-by: Samuel Young <samuel.young@softwire.com>
pull/3169/head^2
Nat Dean-Lewis 2 months ago committed by GitHub
parent
commit
02f319396b
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
  1. 35
      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. 251
      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. 244
      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

35
app/helpers/bulk_upload/lettings_log_to_csv.rb

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

2
app/models/derived_variables/lettings_log_variables.rb

@ -300,7 +300,7 @@ private
end end
def get_refused 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 0
end 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::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::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::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::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::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?), (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::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::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::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::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::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?), (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?),

8
app/models/form/question.rb

@ -446,6 +446,14 @@ private
sex6: %w[R], sex6: %w[R],
sex7: %w[R], sex7: %w[R],
sex8: %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], relat2: [3],
relat3: [3], relat3: [3],
relat4: [3], relat4: [3],

6
app/models/lettings_log.rb

@ -687,7 +687,7 @@ class LettingsLog < Log
end end
def has_any_person_details?(person_index) 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 end
def details_not_known_for_person?(person_index) def details_not_known_for_person?(person_index)
@ -911,6 +911,10 @@ private
[sex1, sex2, sex3, sex4, sex5, sex6, sex7, sex8].any?("R") [sex1, sex2, sex3, sex4, sex5, sex6, sex7, sex8].any?("R")
end end
def sexrab_refused?
[sexrab1, sexrab2, sexrab3, sexrab4, sexrab5, sexrab6, sexrab7, sexrab8].any?("R")
end
def relat_refused? def relat_refused?
[relat2, relat3, relat4, relat5, relat6, relat7, relat8].any?("R") [relat2, relat3, relat4, relat5, relat6, relat7, relat8].any?("R")
end end

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

@ -4,7 +4,7 @@ class BulkUpload::Lettings::Year2026::CsvParser
include CollectionTimeHelper include CollectionTimeHelper
# TODO: CLDC-4162: Update when 2026 format is known # TODO: CLDC-4162: Update when 2026 format is known
FIELDS = 156 FIELDS = 148
FORM_YEAR = 2026 FORM_YEAR = 2026
attr_reader :path 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_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_41: "What is the length of the fixed-term tenancy to the nearest year?",
field_42: "What is the lead tenant’s age?", 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_44: "Which of these best describes the lead tenant’s ethnic background?",
field_45: "What is the lead tenant’s nationality?", field_45: "What is the lead tenant’s nationality?",
field_46: "Which of these best describes the lead tenant’s working situation?", 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_47: "Is person 2 the partner of the lead tenant?",
field_48: "What is person 2’s age?", 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_50: "Which of these best describes person 2’s working situation?",
field_51: "Is person 3 the partner of the lead tenant?", field_51: "Is person 3 the partner of the lead tenant?",
field_52: "What is person 3’s age?", 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_54: "Which of these best describes person 3’s working situation?",
field_55: "Is person 4 the partner of the lead tenant?", field_55: "Is person 4 the partner of the lead tenant?",
field_56: "What is person 4’s age?", 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_58: "Which of these best describes person 4’s working situation?",
field_59: "Is person 5 the partner of the lead tenant?", field_59: "Is person 5 the partner of the lead tenant?",
field_60: "What is person 5’s age?", 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_62: "Which of these best describes person 5’s working situation?",
field_63: "Is person 6 the partner of the lead tenant?", field_63: "Is person 6 the partner of the lead tenant?",
field_64: "What is person 6’s age?", 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_66: "Which of these best describes person 6’s working situation?",
field_67: "Is person 7 the partner of the lead tenant?", field_67: "Is person 7 the partner of the lead tenant?",
field_68: "What is person 7’s age?", 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_70: "Which of these best describes person 7’s working situation?",
field_71: "Is person 8 the partner of the lead tenant?", field_71: "Is person 8 the partner of the lead tenant?",
field_72: "What is person 8’s age?", 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_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_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?", 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_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_129: "What do you expect the outstanding amount to be?",
field_130: "Lead tenant's sex, as registered at birth", field_130: "Is the gender the lead tenant identifies with the same as their sex registered at birth?",
field_131: "Person 2's sex, as registered at birth", field_131: "If 'No', enter the lead tenant's gender identity",
field_132: "Person 3's sex, as registered at birth", field_132: "Is the gender person 2 identifies with the same as their sex registered at birth?",
field_133: "Person 4's sex, as registered at birth", field_133: "If 'No', enter person 2's gender identity",
field_134: "Person 5's sex, as registered at birth", field_134: "Is the gender person 3 identifies with the same as their sex registered at birth?",
field_135: "Person 6's sex, as registered at birth", field_135: "If 'No', enter person 3's gender identity",
field_136: "Person 7's sex, as registered at birth", field_136: "Is the gender person 4 identifies with the same as their sex registered at birth?",
field_137: "Person 8's sex, as registered at birth", field_137: "If 'No', enter person 4's gender identity",
field_138: "Is the gender the lead tenant identifies with the same as their sex registered at birth?", field_138: "Is the gender person 5 identifies with the same as their sex registered at birth?",
field_139: "If 'No', enter the lead tenant's gender identity", field_139: "If 'No', enter person 5's gender identity",
field_140: "Is the gender person 2 identifies with the same as their sex registered at birth?", field_140: "Is the gender person 6 identifies with the same as their sex registered at birth?",
field_141: "If 'No', enter person 2's gender identity", field_141: "If 'No', enter person 6's gender identity",
field_142: "Is the gender person 3 identifies with the same as their sex registered at birth?", field_142: "Is the gender person 7 identifies with the same as their sex registered at birth?",
field_143: "If 'No', enter person 3's gender identity", field_143: "If 'No', enter person 7's gender identity",
field_144: "Is the gender person 4 identifies with the same as their sex registered at birth?", field_144: "Is the gender person 8 identifies with the same as their sex registered at birth?",
field_145: "If 'No', enter person 4's gender identity", field_145: "If 'No', enter person 8'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_146: "What was the source of referral for this letting? - PRP properties part 1",
field_148: "Is the gender person 6 identifies with the same as their sex registered at birth?", field_147: "What was the source of referral for this letting? - PRP properties part 2",
field_149: "If 'No', enter person 6's gender identity", field_148: "What was the source of referral for this letting? - PRP properties part 3",
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",
}.freeze }.freeze
RENT_TYPE_BU_MAPPING = { RENT_TYPE_BU_MAPPING = {
@ -312,13 +304,13 @@ class BulkUpload::Lettings::Year2026::RowParser
attribute :field_128, :integer attribute :field_128, :integer
attribute :field_129, :decimal attribute :field_129, :decimal
attribute :field_130, :string attribute :field_130, :integer
attribute :field_131, :string attribute :field_131, :string
attribute :field_132, :string attribute :field_132, :integer
attribute :field_133, :string attribute :field_133, :string
attribute :field_134, :string attribute :field_134, :integer
attribute :field_135, :string attribute :field_135, :string
attribute :field_136, :string attribute :field_136, :integer
attribute :field_137, :string attribute :field_137, :string
attribute :field_138, :integer attribute :field_138, :integer
attribute :field_139, :string attribute :field_139, :string
@ -328,18 +320,10 @@ class BulkUpload::Lettings::Year2026::RowParser
attribute :field_143, :string attribute :field_143, :string
attribute :field_144, :integer attribute :field_144, :integer
attribute :field_145, :string attribute :field_145, :string
attribute :field_146, :integer attribute :field_146, :integer
attribute :field_147, :string attribute :field_147, :integer
attribute :field_148, :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 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_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 !supported_housing? ? "field_24" : nil, # postcode # TODO: CLDC-4119: add postcode to hash for supported housing
"field_42", # age1 "field_42", # age1
"field_43", # sex1 "field_43", # sexrab1
"field_130", # sexrab1
"field_46", # ecstat1 "field_46", # ecstat1
) )
if [field_124, field_125, field_126, field_127].all?(&:present?) if [field_124, field_125, field_126, field_127].all?(&:present?)
@ -748,7 +731,6 @@ private
"startdate", "startdate",
"age1", "age1",
"sexrab1", "sexrab1",
"sex1",
"ecstat1", "ecstat1",
"owning_organisation", "owning_organisation",
"tcharge", "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_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_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_42, error_message) # age1
errors.add(:field_130, error_message) # sexrab1 errors.add(:field_43, error_message) # sexrab1
errors.add(:field_43, error_message) # sex1
errors.add(:field_46, error_message) # ecstat1 errors.add(:field_46, error_message) # ecstat1
errors.add(:field_122, error_message) unless general_needs? # household_charge errors.add(:field_122, error_message) unless general_needs? # household_charge
errors.add(:field_124, error_message) # brent errors.add(:field_124, error_message) # brent
@ -1051,31 +1032,31 @@ private
def field_referral_register_prp_valid? def field_referral_register_prp_valid?
if owning_organisation&.prp? if owning_organisation&.prp?
[5, 6, 7, 8, 9].include?(field_154) [5, 6, 7, 8, 9].include?(field_146)
else else
field_154.blank? field_146.blank?
end end
end end
def field_referral_noms_valid? def field_referral_noms_valid?
case field_154 case field_146
when 6 when 6
[1, 2, 3, 4].include?(field_155) [1, 2, 3, 4].include?(field_147)
when 7 when 7
[5, 6, 7, 8].include?(field_155) [5, 6, 7, 8].include?(field_147)
else else
field_155.blank? field_147.blank?
end end
end end
def field_referral_org_valid? def field_referral_org_valid?
case field_155 case field_147
when 1 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 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 else
field_156.blank? field_148.blank?
end end
end end
@ -1087,7 +1068,7 @@ private
return if renewal? return if renewal?
return if referral_fields_valid? 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")) errors.add(field, I18n.t("#{ERROR_BASE_KEY}.referral.invalid_option"))
end end
end end
@ -1140,14 +1121,14 @@ private
age8_known: %i[field_72], age8_known: %i[field_72],
age8: %i[field_72], age8: %i[field_72],
sex1: %i[field_43], sexrab1: %i[field_43],
sex2: %i[field_49], sexrab2: %i[field_49],
sex3: %i[field_53], sexrab3: %i[field_53],
sex4: %i[field_57], sexrab4: %i[field_57],
sex5: %i[field_61], sexrab5: %i[field_61],
sex6: %i[field_65], sexrab6: %i[field_65],
sex7: %i[field_69], sexrab7: %i[field_69],
sex8: %i[field_73], sexrab8: %i[field_73],
ethnic_group: %i[field_44], ethnic_group: %i[field_44],
ethnic: %i[field_44], ethnic: %i[field_44],
@ -1204,9 +1185,9 @@ private
accessible_register: %i[field_115], accessible_register: %i[field_115],
letting_allocation: %i[field_112 field_113 field_114 field_115], letting_allocation: %i[field_112 field_113 field_114 field_115],
referral_register: %i[field_116 field_154], referral_register: %i[field_116 field_146],
referral_noms: %i[field_155], referral_noms: %i[field_147],
referral_org: %i[field_156], referral_org: %i[field_148],
net_income_known: %i[field_117], net_income_known: %i[field_117],
incfreq: %i[field_118], incfreq: %i[field_118],
@ -1255,30 +1236,22 @@ private
county: [:field_22], county: [:field_22],
uprn_selection: [:field_19], uprn_selection: [:field_19],
sexrab1: %i[field_130], gender_same_as_sex1: %i[field_130],
sexrab2: %i[field_131], gender_same_as_sex2: %i[field_132],
sexrab3: %i[field_132], gender_same_as_sex3: %i[field_134],
sexrab4: %i[field_133], gender_same_as_sex4: %i[field_136],
sexrab5: %i[field_134], gender_same_as_sex5: %i[field_138],
sexrab6: %i[field_135], gender_same_as_sex6: %i[field_140],
sexrab7: %i[field_136], gender_same_as_sex7: %i[field_142],
sexrab8: %i[field_137], gender_same_as_sex8: %i[field_144],
gender_same_as_sex1: %i[field_138], gender_description1: %i[field_131],
gender_same_as_sex2: %i[field_140], gender_description2: %i[field_133],
gender_same_as_sex3: %i[field_142], gender_description3: %i[field_135],
gender_same_as_sex4: %i[field_144], gender_description4: %i[field_137],
gender_same_as_sex5: %i[field_146], gender_description5: %i[field_139],
gender_same_as_sex6: %i[field_148], gender_description6: %i[field_141],
gender_same_as_sex7: %i[field_150], gender_description7: %i[field_143],
gender_same_as_sex8: %i[field_152], gender_description8: %i[field_145],
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],
}.compact }.compact
end end
@ -1340,14 +1313,14 @@ private
attributes["age8_known"] = age8_known? 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["age8"] = field_72 if attributes["age8_known"]&.zero? && field_72&.match(/\A\d{1,3}\z|\AR\z/)
attributes["sex1"] = field_43 attributes["sexrab1"] = field_43
attributes["sex2"] = field_49 attributes["sexrab2"] = field_49
attributes["sex3"] = field_53 attributes["sexrab3"] = field_53
attributes["sex4"] = field_57 attributes["sexrab4"] = field_57
attributes["sex5"] = field_61 attributes["sexrab5"] = field_61
attributes["sex6"] = field_65 attributes["sexrab6"] = field_65
attributes["sex7"] = field_69 attributes["sexrab7"] = field_69
attributes["sex8"] = field_73 attributes["sexrab8"] = field_73
attributes["ethnic_group"] = ethnic_group_from_ethnic attributes["ethnic_group"] = ethnic_group_from_ethnic
attributes["ethnic"] = field_44 attributes["ethnic"] = field_44
@ -1486,30 +1459,22 @@ private
attributes["postcode_full_input"] = postcode_full attributes["postcode_full_input"] = postcode_full
attributes["select_best_address_match"] = true if field_18.blank? attributes["select_best_address_match"] = true if field_18.blank?
attributes["sexrab1"] = field_130 attributes["gender_same_as_sex1"] = field_130
attributes["sexrab2"] = field_131 attributes["gender_description1"] = field_131
attributes["sexrab3"] = field_132 attributes["gender_same_as_sex2"] = field_132
attributes["sexrab4"] = field_133 attributes["gender_description2"] = field_133
attributes["sexrab5"] = field_134 attributes["gender_same_as_sex3"] = field_134
attributes["sexrab6"] = field_135 attributes["gender_description3"] = field_135
attributes["sexrab7"] = field_136 attributes["gender_same_as_sex4"] = field_136
attributes["sexrab8"] = field_137 attributes["gender_description4"] = field_137
attributes["gender_same_as_sex1"] = field_138 attributes["gender_same_as_sex5"] = field_138
attributes["gender_description1"] = field_139 attributes["gender_description5"] = field_139
attributes["gender_same_as_sex2"] = field_140 attributes["gender_same_as_sex6"] = field_140
attributes["gender_description2"] = field_141 attributes["gender_description6"] = field_141
attributes["gender_same_as_sex3"] = field_142 attributes["gender_same_as_sex7"] = field_142
attributes["gender_description3"] = field_143 attributes["gender_description7"] = field_143
attributes["gender_same_as_sex4"] = field_144 attributes["gender_same_as_sex8"] = field_144
attributes["gender_description4"] = field_145 attributes["gender_description8"] = 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 attributes
end end
@ -1617,31 +1582,31 @@ private
end end
def person_2_present? 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 end
def person_3_present? 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 end
def person_4_present? 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 end
def person_5_present? 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 end
def person_6_present? 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 end
def person_7_present? 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 end
def person_8_present? 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 end
def leftreg def leftreg
@ -1847,7 +1812,7 @@ private
if owning_organisation.la? if owning_organisation.la?
field_116 field_116
else else
field_154 field_146
end end
end end
@ -1856,7 +1821,7 @@ private
return unless referral_fields_valid? return unless referral_fields_valid?
if owning_organisation.prp? if owning_organisation.prp?
field_155 field_147
end end
end end
@ -1865,7 +1830,7 @@ private
return unless referral_fields_valid? return unless referral_fields_valid?
if owning_organisation.prp? if owning_organisation.prp?
field_156 field_148
end end
end end
end end

17
app/services/exports/lettings_log_export_constants.rb

@ -140,7 +140,6 @@ module Exports::LettingsLogExportConstants
(1..8).each do |index| (1..8).each do |index|
ALL_YEAR_EXPORT_FIELDS << "age#{index}" ALL_YEAR_EXPORT_FIELDS << "age#{index}"
ALL_YEAR_EXPORT_FIELDS << "ecstat#{index}" ALL_YEAR_EXPORT_FIELDS << "ecstat#{index}"
ALL_YEAR_EXPORT_FIELDS << "sex#{index}"
end end
(2..8).each do |index| (2..8).each do |index|
ALL_YEAR_EXPORT_FIELDS << "relat#{index}" ALL_YEAR_EXPORT_FIELDS << "relat#{index}"
@ -159,6 +158,9 @@ module Exports::LettingsLogExportConstants
"offered", "offered",
"referral", "referral",
] ]
(1..8).each do |index|
YEAR_2021_EXPORT_FIELDS << "sex#{index}"
end
YEAR_2022_EXPORT_FIELDS = Set[ YEAR_2022_EXPORT_FIELDS = Set[
"builtype", "builtype",
@ -167,6 +169,9 @@ module Exports::LettingsLogExportConstants
"offered", "offered",
"referral", "referral",
] ]
(1..8).each do |index|
YEAR_2022_EXPORT_FIELDS << "sex#{index}"
end
YEAR_2023_EXPORT_FIELDS = Set[ YEAR_2023_EXPORT_FIELDS = Set[
"builtype", "builtype",
@ -175,6 +180,9 @@ module Exports::LettingsLogExportConstants
"offered", "offered",
"referral", "referral",
] ]
(1..8).each do |index|
YEAR_2023_EXPORT_FIELDS << "sex#{index}"
end
YEAR_2024_EXPORT_FIELDS = Set[ YEAR_2024_EXPORT_FIELDS = Set[
"builtype", "builtype",
@ -196,6 +204,9 @@ module Exports::LettingsLogExportConstants
"carehome_charges_value_check", "carehome_charges_value_check",
"referral", "referral",
] ]
(1..8).each do |index|
YEAR_2024_EXPORT_FIELDS << "sex#{index}"
end
YEAR_2025_EXPORT_FIELDS = Set[ YEAR_2025_EXPORT_FIELDS = Set[
"builtype", "builtype",
@ -215,6 +226,9 @@ module Exports::LettingsLogExportConstants
"supcharg_value_check", "supcharg_value_check",
"referral", "referral",
] ]
(1..8).each do |index|
YEAR_2025_EXPORT_FIELDS << "sex#{index}"
end
YEAR_2026_EXPORT_FIELDS = Set[ YEAR_2026_EXPORT_FIELDS = Set[
"accessible_register", "accessible_register",
@ -235,7 +249,6 @@ module Exports::LettingsLogExportConstants
"referral_noms", "referral_noms",
"referral_org", "referral_org",
] ]
(1..8).each do |index| (1..8).each do |index|
YEAR_2026_EXPORT_FIELDS << "sexrab#{index}" YEAR_2026_EXPORT_FIELDS << "sexrab#{index}"
YEAR_2026_EXPORT_FIELDS << "gender_same_as_sex#{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> <tenancycode>BZ737</tenancycode>
<age1>35</age1> <age1>35</age1>
<sexrab1>F</sexrab1> <sexrab1>F</sexrab1>
<sex1>F</sex1>
<gender_same_as_sex1>1</gender_same_as_sex1> <gender_same_as_sex1>1</gender_same_as_sex1>
<gender_description1/> <gender_description1/>
<ethnic>2</ethnic> <ethnic>2</ethnic>
@ -14,43 +13,36 @@
<hhmemb>2</hhmemb> <hhmemb>2</hhmemb>
<age2>32</age2> <age2>32</age2>
<sexrab2>M</sexrab2> <sexrab2>M</sexrab2>
<sex2>M</sex2>
<gender_same_as_sex2>2</gender_same_as_sex2> <gender_same_as_sex2>2</gender_same_as_sex2>
<gender_description2>Non-binary</gender_description2> <gender_description2>Non-binary</gender_description2>
<ecstat2>6</ecstat2> <ecstat2>6</ecstat2>
<age3/> <age3/>
<sexrab3/> <sexrab3/>
<sex3/>
<gender_same_as_sex3/> <gender_same_as_sex3/>
<gender_description3/> <gender_description3/>
<ecstat3/> <ecstat3/>
<age4/> <age4/>
<sexrab4/> <sexrab4/>
<sex4/>
<gender_same_as_sex4/> <gender_same_as_sex4/>
<gender_description4/> <gender_description4/>
<ecstat4/> <ecstat4/>
<age5/> <age5/>
<sexrab5/> <sexrab5/>
<sex5/>
<gender_same_as_sex5/> <gender_same_as_sex5/>
<gender_description5/> <gender_description5/>
<ecstat5/> <ecstat5/>
<age6/> <age6/>
<sexrab6/> <sexrab6/>
<sex6/>
<gender_same_as_sex6/> <gender_same_as_sex6/>
<gender_description6/> <gender_description6/>
<ecstat6/> <ecstat6/>
<age7/> <age7/>
<sexrab7/> <sexrab7/>
<sex7/>
<gender_same_as_sex7/> <gender_same_as_sex7/>
<gender_description7/> <gender_description7/>
<ecstat7/> <ecstat7/>
<age8/> <age8/>
<sexrab8/> <sexrab8/>
<sex8/>
<gender_same_as_sex8/> <gender_same_as_sex8/>
<gender_description8/> <gender_description8/>
<ecstat8/> <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

@ -346,7 +346,6 @@ RSpec.describe Form::Lettings::Subsections::HouseholdCharacteristics, type: :mod
age_lead_tenant_over_retirement_value_check age_lead_tenant_over_retirement_value_check
lead_tenant_sex_registered_at_birth lead_tenant_sex_registered_at_birth
lead_tenant_gender_same_as_sex lead_tenant_gender_same_as_sex
lead_tenant_gender_identity
no_household_member_likely_to_be_pregnant_lead_check no_household_member_likely_to_be_pregnant_lead_check
gender_lead_tenant_over_retirement_value_check gender_lead_tenant_over_retirement_value_check
lead_tenant_ethnic_group lead_tenant_ethnic_group
@ -369,7 +368,6 @@ RSpec.describe Form::Lettings::Subsections::HouseholdCharacteristics, type: :mod
age_2_over_retirement_value_check age_2_over_retirement_value_check
person_2_sex_registered_at_birth person_2_sex_registered_at_birth
person_2_gender_same_as_sex person_2_gender_same_as_sex
person_2_gender_identity
no_household_member_likely_to_be_pregnant_person_2_check no_household_member_likely_to_be_pregnant_person_2_check
gender_2_over_retirement_value_check gender_2_over_retirement_value_check
person_2_working_situation person_2_working_situation
@ -385,7 +383,6 @@ RSpec.describe Form::Lettings::Subsections::HouseholdCharacteristics, type: :mod
age_3_over_retirement_value_check age_3_over_retirement_value_check
person_3_sex_registered_at_birth person_3_sex_registered_at_birth
person_3_gender_same_as_sex person_3_gender_same_as_sex
person_3_gender_identity
no_household_member_likely_to_be_pregnant_person_3_check no_household_member_likely_to_be_pregnant_person_3_check
gender_3_over_retirement_value_check gender_3_over_retirement_value_check
person_3_working_situation person_3_working_situation
@ -401,7 +398,6 @@ RSpec.describe Form::Lettings::Subsections::HouseholdCharacteristics, type: :mod
age_4_over_retirement_value_check age_4_over_retirement_value_check
person_4_sex_registered_at_birth person_4_sex_registered_at_birth
person_4_gender_same_as_sex person_4_gender_same_as_sex
person_4_gender_identity
no_household_member_likely_to_be_pregnant_person_4_check no_household_member_likely_to_be_pregnant_person_4_check
gender_4_over_retirement_value_check gender_4_over_retirement_value_check
person_4_working_situation person_4_working_situation
@ -417,7 +413,6 @@ RSpec.describe Form::Lettings::Subsections::HouseholdCharacteristics, type: :mod
age_5_over_retirement_value_check age_5_over_retirement_value_check
person_5_sex_registered_at_birth person_5_sex_registered_at_birth
person_5_gender_same_as_sex person_5_gender_same_as_sex
person_5_gender_identity
no_household_member_likely_to_be_pregnant_person_5_check no_household_member_likely_to_be_pregnant_person_5_check
gender_5_over_retirement_value_check gender_5_over_retirement_value_check
person_5_working_situation person_5_working_situation
@ -433,7 +428,6 @@ RSpec.describe Form::Lettings::Subsections::HouseholdCharacteristics, type: :mod
age_6_over_retirement_value_check age_6_over_retirement_value_check
person_6_sex_registered_at_birth person_6_sex_registered_at_birth
person_6_gender_same_as_sex person_6_gender_same_as_sex
person_6_gender_identity
no_household_member_likely_to_be_pregnant_person_6_check no_household_member_likely_to_be_pregnant_person_6_check
gender_6_over_retirement_value_check gender_6_over_retirement_value_check
person_6_working_situation person_6_working_situation
@ -449,7 +443,6 @@ RSpec.describe Form::Lettings::Subsections::HouseholdCharacteristics, type: :mod
age_7_over_retirement_value_check age_7_over_retirement_value_check
person_7_sex_registered_at_birth person_7_sex_registered_at_birth
person_7_gender_same_as_sex person_7_gender_same_as_sex
person_7_gender_identity
no_household_member_likely_to_be_pregnant_person_7_check no_household_member_likely_to_be_pregnant_person_7_check
gender_7_over_retirement_value_check gender_7_over_retirement_value_check
person_7_working_situation person_7_working_situation
@ -465,7 +458,6 @@ RSpec.describe Form::Lettings::Subsections::HouseholdCharacteristics, type: :mod
age_8_over_retirement_value_check age_8_over_retirement_value_check
person_8_sex_registered_at_birth person_8_sex_registered_at_birth
person_8_gender_same_as_sex person_8_gender_same_as_sex
person_8_gender_identity
no_household_member_likely_to_be_pregnant_person_8_check no_household_member_likely_to_be_pregnant_person_8_check
gender_8_over_retirement_value_check gender_8_over_retirement_value_check
person_8_working_situation 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.tenant_code).to eql(log.tenancycode)
expect(error.property_ref).to eql(log.propcode) expect(error.property_ref).to eql(log.propcode)
expect(error.row).to eql("2") 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.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("EH") # 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 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 end
it "returns correct column" do it "returns correct column" do
expect(service.column_for_field("field_5")).to eql("AI") expect(service.column_for_field("field_5")).to eql("AA")
expect(service.column_for_field("field_22")).to eql("BR") expect(service.column_for_field("field_22")).to eql("BK")
expect(service.column_for_field("field_26")).to eql("CG") expect(service.column_for_field("field_26")).to eql("BZ")
expect(service.column_for_field("field_25")).to eql("E") expect(service.column_for_field("field_25")).to eql("S")
end end
end 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_18: "12",
field_130: "F", field_130: "1",
field_131: "M", field_131: "",
field_132: "R", field_132: "2",
field_133: "F", field_133: "identity",
field_134: "M", field_134: "3",
field_135: "R", field_135: "",
field_136: "F", field_136: "1",
field_137: "M", field_137: "",
field_138: "1", field_138: "2",
field_139: "", field_139: "identity",
field_140: "2", field_140: "3",
field_141: "identity", field_141: "",
field_142: "3", field_142: "1",
field_143: "", field_143: "",
field_144: "1", field_144: "2",
field_145: "", field_145: "identity",
field_146: "2",
field_147: "identity",
field_148: "3",
field_149: "",
field_150: "1",
field_151: "",
field_152: "2",
field_153: "identity",
} }
end end
@ -323,7 +315,7 @@ RSpec.describe BulkUpload::Lettings::Year2026::RowParser do
:field_24, # postcode_full :field_24, # postcode_full
:field_25, # LA :field_25, # LA
:field_42, # age1 :field_42, # age1
:field_43, # sex1 :field_43, # sexrab1
:field_46, # ecstat1 :field_46, # ecstat1
:field_124, # brent :field_124, # brent
:field_125, # scharge :field_125, # scharge
@ -377,7 +369,7 @@ RSpec.describe BulkUpload::Lettings::Year2026::RowParser do
:field_13, # tenancycode :field_13, # tenancycode
:field_6, # location :field_6, # location
:field_42, # age1 :field_42, # age1
:field_43, # sex1 :field_43, # sexrab1
:field_46, # ecstat1 :field_46, # ecstat1
:field_124, # brent :field_124, # brent
:field_125, # scharge :field_125, # scharge
@ -419,7 +411,7 @@ RSpec.describe BulkUpload::Lettings::Year2026::RowParser do
:field_13, # tenancycode :field_13, # tenancycode
:field_6, # location :field_6, # location
:field_42, # age1 :field_42, # age1
:field_43, # sex1 :field_43, # sexrab1
:field_46, # ecstat1 :field_46, # ecstat1
:field_124, # brent :field_124, # brent
:field_125, # scharge :field_125, # scharge
@ -462,7 +454,7 @@ RSpec.describe BulkUpload::Lettings::Year2026::RowParser do
:field_13, # tenancycode :field_13, # tenancycode
:field_6, # location :field_6, # location
:field_42, # age1 :field_42, # age1
:field_43, # sex1 :field_43, # sexrab1
:field_46, # ecstat1 :field_46, # ecstat1
].each do |field| ].each do |field|
expect(parser.errors[field]).to include(error_message) expect(parser.errors[field]).to include(error_message)
@ -508,7 +500,7 @@ RSpec.describe BulkUpload::Lettings::Year2026::RowParser do
:field_13, # tenancycode :field_13, # tenancycode
:field_6, # location :field_6, # location
:field_42, # age1 :field_42, # age1
:field_43, # sex1 :field_43, # sexrab1
:field_46, # ecstat1 :field_46, # ecstat1
:field_122, # household_charge :field_122, # household_charge
].each do |field| ].each do |field|
@ -562,7 +554,7 @@ RSpec.describe BulkUpload::Lettings::Year2026::RowParser do
:field_24, # postcode_full :field_24, # postcode_full
:field_25, # LA :field_25, # LA
:field_42, # age1 :field_42, # age1
:field_43, # sex1 :field_43, # sexrab1
:field_46, # ecstat1 :field_46, # ecstat1
].each do |field| ].each do |field|
expect(parser.errors[field]).to be_blank 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 it "fetches the question's check_answer_label if it exists" do
parser.valid? 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
end end
@ -1160,7 +1152,7 @@ RSpec.describe BulkUpload::Lettings::Year2026::RowParser do
end end
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 context "when org is LA" do
let(:owning_org) { create(:organisation, :la, :with_old_visible_id) } 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 it "does not add an error" do
parser.valid? parser.valid?
expect(parser.errors[:field_116]).to be_blank expect(parser.errors[:field_116]).to be_blank
expect(parser.errors[:field_154]).to be_blank expect(parser.errors[:field_146]).to be_blank
expect(parser.errors[:field_155]).to be_blank expect(parser.errors[:field_147]).to be_blank
expect(parser.errors[:field_156]).to be_blank expect(parser.errors[:field_148]).to be_blank
end end
end end
@ -1187,9 +1179,9 @@ RSpec.describe BulkUpload::Lettings::Year2026::RowParser do
it "adds errors to all referral fields" do it "adds errors to all referral fields" do
parser.valid? parser.valid?
expect(parser.errors[:field_116]).to be_present expect(parser.errors[:field_116]).to be_present
expect(parser.errors[:field_154]).to be_present expect(parser.errors[:field_146]).to be_present
expect(parser.errors[:field_155]).to be_present expect(parser.errors[:field_147]).to be_present
expect(parser.errors[:field_156]).to be_present expect(parser.errors[:field_148]).to be_present
end end
end end
@ -1199,34 +1191,34 @@ RSpec.describe BulkUpload::Lettings::Year2026::RowParser do
it "adds errors to all referral fields" do it "adds errors to all referral fields" do
parser.valid? parser.valid?
expect(parser.errors[:field_116]).to be_present expect(parser.errors[:field_116]).to be_present
expect(parser.errors[:field_154]).to be_present expect(parser.errors[:field_146]).to be_present
expect(parser.errors[:field_155]).to be_present expect(parser.errors[:field_147]).to be_present
expect(parser.errors[:field_156]).to be_present expect(parser.errors[:field_148]).to be_present
end end
end end
context "and other fields are given" do 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 it "adds errors to all referral fields" do
parser.valid? parser.valid?
expect(parser.errors[:field_116]).to be_present expect(parser.errors[:field_116]).to be_present
expect(parser.errors[:field_154]).to be_present expect(parser.errors[:field_146]).to be_present
expect(parser.errors[:field_155]).to be_present expect(parser.errors[:field_147]).to be_present
expect(parser.errors[:field_156]).to be_present expect(parser.errors[:field_148]).to be_present
end end
end end
end end
context "and is renewal" do 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 it "does not add an error for referral fields" do
parser.valid? parser.valid?
expect(parser.errors[:field_116]).to be_blank expect(parser.errors[:field_116]).to be_blank
expect(parser.errors[:field_154]).to be_blank expect(parser.errors[:field_146]).to be_blank
expect(parser.errors[:field_155]).to be_blank expect(parser.errors[:field_147]).to be_blank
expect(parser.errors[:field_156]).to be_blank expect(parser.errors[:field_148]).to be_blank
end end
end end
end end
@ -1239,141 +1231,141 @@ RSpec.describe BulkUpload::Lettings::Year2026::RowParser do
context "and not renewal" do context "and not renewal" do
let(:renewal_attributes) { org_attributes.merge({ field_7: nil }) } 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 context "and field_146 is valid and does not expect an answer for field_147" do
let(:attributes) { renewal_attributes.merge({ field_154: 5 }) } let(:attributes) { renewal_attributes.merge({ field_146: 5 }) }
it "does not add an error" do it "does not add an error" do
parser.valid? parser.valid?
expect(parser.errors[:field_116]).to be_blank expect(parser.errors[:field_116]).to be_blank
expect(parser.errors[:field_154]).to be_blank expect(parser.errors[:field_146]).to be_blank
expect(parser.errors[:field_155]).to be_blank expect(parser.errors[:field_147]).to be_blank
expect(parser.errors[:field_156]).to be_blank expect(parser.errors[:field_148]).to be_blank
end end
context "and later fields are given" do 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 it "adds errors to all referral fields" do
parser.valid? parser.valid?
expect(parser.errors[:field_116]).to be_present expect(parser.errors[:field_116]).to be_present
expect(parser.errors[:field_154]).to be_present expect(parser.errors[:field_146]).to be_present
expect(parser.errors[:field_155]).to be_present expect(parser.errors[:field_147]).to be_present
expect(parser.errors[:field_156]).to be_present expect(parser.errors[:field_148]).to be_present
end end
end end
end end
context "and field_154 is invalid" do context "and field_146 is invalid" do
let(:attributes) { renewal_attributes.merge({ field_154: 1 }) } # LA option let(:attributes) { renewal_attributes.merge({ field_146: 1 }) } # LA option
it "adds errors to all referral fields" do it "adds errors to all referral fields" do
parser.valid? parser.valid?
expect(parser.errors[:field_116]).to be_present expect(parser.errors[:field_116]).to be_present
expect(parser.errors[:field_154]).to be_present expect(parser.errors[:field_146]).to be_present
expect(parser.errors[:field_155]).to be_present expect(parser.errors[:field_147]).to be_present
expect(parser.errors[:field_156]).to be_present expect(parser.errors[:field_148]).to be_present
end end
end end
context "and field_154 is blank" do context "and field_146 is blank" do
let(:attributes) { renewal_attributes.merge({ field_154: nil }) } let(:attributes) { renewal_attributes.merge({ field_146: nil }) }
it "adds errors to all referral fields" do it "adds errors to all referral fields" do
parser.valid? parser.valid?
expect(parser.errors[:field_116]).to be_present expect(parser.errors[:field_116]).to be_present
expect(parser.errors[:field_154]).to be_present expect(parser.errors[:field_146]).to be_present
expect(parser.errors[:field_155]).to be_present expect(parser.errors[:field_147]).to be_present
expect(parser.errors[:field_156]).to be_present expect(parser.errors[:field_148]).to be_present
end end
end end
context "and field_154 is valid and expects an answer for field_155" do context "and field_146 is valid and expects an answer for field_147" do
let(:field_154_attributes) { renewal_attributes.merge({ field_154: 6 }) } 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 context "and field_147 is valid and does not expect an answer for field_148" do
let(:attributes) { field_154_attributes.merge({ field_155: 2 }) } let(:attributes) { field_146_attributes.merge({ field_147: 2 }) }
it "does not add an error" do it "does not add an error" do
parser.valid? parser.valid?
expect(parser.errors[:field_116]).to be_blank expect(parser.errors[:field_116]).to be_blank
expect(parser.errors[:field_154]).to be_blank expect(parser.errors[:field_146]).to be_blank
expect(parser.errors[:field_155]).to be_blank expect(parser.errors[:field_147]).to be_blank
expect(parser.errors[:field_156]).to be_blank expect(parser.errors[:field_148]).to be_blank
end end
context "and later fields are given" do 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 it "adds errors to all referral fields" do
parser.valid? parser.valid?
expect(parser.errors[:field_116]).to be_present expect(parser.errors[:field_116]).to be_present
expect(parser.errors[:field_154]).to be_present expect(parser.errors[:field_146]).to be_present
expect(parser.errors[:field_155]).to be_present expect(parser.errors[:field_147]).to be_present
expect(parser.errors[:field_156]).to be_present expect(parser.errors[:field_148]).to be_present
end end
end end
end end
context "and field_155 is invalid" do context "and field_147 is invalid" do
let(:attributes) { field_154_attributes.merge({ field_155: 5 }) } # needs field_154 to be 7 let(:attributes) { field_146_attributes.merge({ field_147: 5 }) } # needs field_146 to be 7
it "adds errors to all referral fields" do it "adds errors to all referral fields" do
parser.valid? parser.valid?
expect(parser.errors[:field_116]).to be_present expect(parser.errors[:field_116]).to be_present
expect(parser.errors[:field_154]).to be_present expect(parser.errors[:field_146]).to be_present
expect(parser.errors[:field_155]).to be_present expect(parser.errors[:field_147]).to be_present
expect(parser.errors[:field_156]).to be_present expect(parser.errors[:field_148]).to be_present
end end
end end
context "and field_155 is blank" do context "and field_147 is blank" do
let(:attributes) { field_154_attributes.merge({ field_155: nil }) } let(:attributes) { field_146_attributes.merge({ field_147: nil }) }
it "adds errors to all referral fields" do it "adds errors to all referral fields" do
parser.valid? parser.valid?
expect(parser.errors[:field_116]).to be_present expect(parser.errors[:field_116]).to be_present
expect(parser.errors[:field_154]).to be_present expect(parser.errors[:field_146]).to be_present
expect(parser.errors[:field_155]).to be_present expect(parser.errors[:field_147]).to be_present
expect(parser.errors[:field_156]).to be_present expect(parser.errors[:field_148]).to be_present
end end
end end
context "and field_155 is valid and expects an answer for field_156" do context "and field_147 is valid and expects an answer for field_148" do
let(:field_155_attributes) { field_154_attributes.merge({ field_155: 1 }) } let(:field_147_attributes) { field_146_attributes.merge({ field_147: 1 }) }
context "and field_156 is valid" do context "and field_148 is valid" do
let(:attributes) { field_155_attributes.merge({ field_156: 1 }) } let(:attributes) { field_147_attributes.merge({ field_148: 1 }) }
it "does not add an error" do it "does not add an error" do
parser.valid? parser.valid?
expect(parser.errors[:field_116]).to be_blank expect(parser.errors[:field_116]).to be_blank
expect(parser.errors[:field_154]).to be_blank expect(parser.errors[:field_146]).to be_blank
expect(parser.errors[:field_155]).to be_blank expect(parser.errors[:field_147]).to be_blank
expect(parser.errors[:field_156]).to be_blank expect(parser.errors[:field_148]).to be_blank
end end
end end
context "and field_156 is invalid" do context "and field_148 is invalid" do
let(:attributes) { field_155_attributes.merge({ field_156: 11 }) } # needs field_155 to be 7 let(:attributes) { field_147_attributes.merge({ field_148: 11 }) } # needs field_147 to be 7
it "adds errors to all referral fields" do it "adds errors to all referral fields" do
parser.valid? parser.valid?
expect(parser.errors[:field_116]).to be_present expect(parser.errors[:field_116]).to be_present
expect(parser.errors[:field_154]).to be_present expect(parser.errors[:field_146]).to be_present
expect(parser.errors[:field_155]).to be_present expect(parser.errors[:field_147]).to be_present
expect(parser.errors[:field_156]).to be_present expect(parser.errors[:field_148]).to be_present
end end
end end
context "and field_156 is blank" do context "and field_148 is blank" do
let(:attributes) { field_155_attributes.merge({ field_156: nil }) } let(:attributes) { field_147_attributes.merge({ field_148: nil }) }
it "adds errors to all referral fields" do it "adds errors to all referral fields" do
parser.valid? parser.valid?
expect(parser.errors[:field_116]).to be_present expect(parser.errors[:field_116]).to be_present
expect(parser.errors[:field_154]).to be_present expect(parser.errors[:field_146]).to be_present
expect(parser.errors[:field_155]).to be_present expect(parser.errors[:field_147]).to be_present
expect(parser.errors[:field_156]).to be_present expect(parser.errors[:field_148]).to be_present
end end
end end
end end
@ -1381,14 +1373,14 @@ RSpec.describe BulkUpload::Lettings::Year2026::RowParser do
end end
context "and is renewal" do 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 it "does not add an error for referral fields" do
parser.valid? parser.valid?
expect(parser.errors[:field_116]).to be_blank expect(parser.errors[:field_116]).to be_blank
expect(parser.errors[:field_154]).to be_blank expect(parser.errors[:field_146]).to be_blank
expect(parser.errors[:field_155]).to be_blank expect(parser.errors[:field_147]).to be_blank
expect(parser.errors[:field_156]).to be_blank expect(parser.errors[:field_148]).to be_blank
end end
end end
end end
@ -2084,22 +2076,22 @@ RSpec.describe BulkUpload::Lettings::Year2026::RowParser do
end end
context "when a soft validation is triggered that relates both to fields that are and are not routed to" 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_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 it "adds errors to fields that are routed to" do
parser.valid? 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_130, category: :soft_validation)).to be_present
expect(parser.errors.where(:field_138, category: :soft_validation)).to be_present expect(parser.errors.where(:field_49, category: :soft_validation)).to be_present
expect(parser.errors.where(:field_131, category: :soft_validation)).to be_present expect(parser.errors.where(:field_132, category: :soft_validation)).to be_present
expect(parser.errors.where(:field_140, category: :soft_validation)).to be_present
end end
it "does not add errors to fields that are not routed to" do it "does not add errors to fields that are not routed to" do
parser.valid? parser.valid?
expect(parser.errors.where(:field_133, 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_144, 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_134, 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_146, category: :soft_validation)).not_to be_present expect(parser.errors.where(:field_138, category: :soft_validation)).not_to be_present
end end
end end
@ -2501,7 +2493,7 @@ RSpec.describe BulkUpload::Lettings::Year2026::RowParser do
end end
end end
describe "#sexN fields" do describe "#sexrabN fields" do
let(:attributes) do let(:attributes) do
{ {
bulk_upload:, bulk_upload:,
@ -2517,14 +2509,14 @@ RSpec.describe BulkUpload::Lettings::Year2026::RowParser do
end end
it "sets value from correct mapping" do it "sets value from correct mapping" do
expect(parser.log.sex1).to eql("F") expect(parser.log.sexrab1).to eql("F")
expect(parser.log.sex2).to eql("M") expect(parser.log.sexrab2).to eql("M")
expect(parser.log.sex3).to eql("X") expect(parser.log.sexrab3).to eql("X")
expect(parser.log.sex4).to eql("R") expect(parser.log.sexrab4).to eql("R")
expect(parser.log.sex5).to eql("F") expect(parser.log.sexrab5).to eql("F")
expect(parser.log.sex6).to eql("M") expect(parser.log.sexrab6).to eql("M")
expect(parser.log.sex7).to eql("X") expect(parser.log.sexrab7).to eql("X")
expect(parser.log.sex8).to eql("R") expect(parser.log.sexrab8).to eql("R")
end end
end end

3
spec/services/csv/lettings_log_csv_service_spec.rb

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

18
spec/services/exports/lettings_log_export_service_spec.rb

@ -83,7 +83,7 @@ RSpec.describe Exports::LettingsLogExportService do
end end
context "and one lettings log is available for export" do 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 it "generates a ZIP export file with the expected filename" do
expect(storage_service).to receive(:write_file).with(expected_zip_filename, any_args) expect(storage_service).to receive(:write_file).with(expected_zip_filename, any_args)
@ -127,7 +127,7 @@ RSpec.describe Exports::LettingsLogExportService do
end end
context "and one lettings log with unknown user details is available for export" do 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) def replace_person_details(export_file)
export_file.sub!("<age2>32</age2>", "<age2>-9</age2>") export_file.sub!("<age2>32</age2>", "<age2>-9</age2>")
@ -180,7 +180,7 @@ RSpec.describe Exports::LettingsLogExportService do
end end
context "and one lettings log is available for export" do 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_zip_filename) { "core_2023_2024_apr_mar_f0001_inc0001.zip" }
let(:expected_data_filename) { "core_2023_2024_apr_mar_f0001_inc0001_pt001.xml" } 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") } 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 end
context "and one lettings log with duplicate reference is available for export" do 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) def replace_duplicate_set_id(export_file)
export_file.sub!("<duplicate_set_id/>", "<duplicate_set_id>123</duplicate_set_id>") export_file.sub!("<duplicate_set_id/>", "<duplicate_set_id>123</duplicate_set_id>")
@ -433,7 +433,7 @@ RSpec.describe Exports::LettingsLogExportService do
end end
context "and one lettings log is available for export" do 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_zip_filename) { "core_2024_2025_apr_mar_f0001_inc0001.zip" }
let(:expected_data_filename) { "core_2024_2025_apr_mar_f0001_inc0001_pt001.xml" } 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") } 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 end
context "and one lettings log is available for export" do 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_zip_filename) { "core_2025_2026_apr_mar_f0001_inc0001.zip" }
let(:expected_data_filename) { "core_2025_2026_apr_mar_f0001_inc0001_pt001.xml" } 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") } 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, assigned_to: user,
age1: 35, age1: 35,
sexrab1: "F", sexrab1: "F",
sex1: "F", sex1: nil,
age2: 32, age2: 32,
sexrab2: "M", sexrab2: "M",
sex2: "M", sex2: nil,
ppostcode_full: "A1 1AA", ppostcode_full: "A1 1AA",
nationality_all_group: 13, nationality_all_group: 13,
propcode: "123", propcode: "123",
@ -643,7 +643,7 @@ RSpec.describe Exports::LettingsLogExportService do
let(:scheme) { FactoryBot.create(:scheme, :export, owning_organisation: organisation) } 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(: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 before do
lettings_log.postcode_full = nil lettings_log.postcode_full = nil

Loading…
Cancel
Save