Browse Source

Merge branch 'main' into CLDC-4175-new-service-charge-question-sales

# Conflicts:
#	app/helpers/bulk_upload/sales_log_to_csv.rb
#	app/services/bulk_upload/sales/year2026/csv_parser.rb
#	app/services/bulk_upload/sales/year2026/row_parser.rb
#	db/schema.rb
#	spec/fixtures/files/2026_27_sales_bulk_upload.csv
#	spec/fixtures/files/sales_logs_csv_export_codes_26.csv
#	spec/fixtures/files/sales_logs_csv_export_labels_26.csv
#	spec/fixtures/files/sales_logs_csv_export_non_support_codes_26.csv
#	spec/fixtures/files/sales_logs_csv_export_non_support_labels_26.csv
#	spec/fixtures/variable_definitions/sales_download_26_27.csv
#	spec/lib/tasks/log_variable_definitions_spec.rb
#	spec/services/bulk_upload/sales/year2026/row_parser_spec.rb
pull/3200/head
Nat Dean-Lewis 2 months ago
parent
commit
a2a753d5be
  1. 15
      app/helpers/bulk_upload/sales_log_to_csv.rb
  2. 12
      app/models/derived_variables/lettings_log_variables.rb
  3. 2
      app/models/derived_variables/sales_log_variables.rb
  4. 21
      app/models/form/sales/pages/buyer1_gender_same_as_sex.rb
  5. 23
      app/models/form/sales/pages/buyer2_gender_same_as_sex.rb
  6. 16
      app/models/form/sales/pages/person_gender_same_as_sex.rb
  7. 16
      app/models/form/sales/questions/gender_description.rb
  8. 33
      app/models/form/sales/questions/gender_same_as_sex.rb
  9. 3
      app/models/form/sales/subsections/household_characteristics.rb
  10. 13
      app/models/log.rb
  11. 4
      app/services/bulk_upload/sales/year2026/csv_parser.rb
  12. 77
      app/services/bulk_upload/sales/year2026/row_parser.rb
  13. 1
      app/services/csv/sales_log_csv_service.rb
  14. 2
      app/services/exports/sales_log_export_constants.rb
  15. 16
      config/locales/forms/2026/lettings/household_characteristics.en.yml
  16. 91
      config/locales/forms/2026/sales/household_characteristics.en.yml
  17. 18
      db/migrate/20260220141000_add_gender_same_as_sex_fields_to_sales_logs.rb
  18. 12
      db/schema.rb
  19. 12
      spec/factories/sales_log.rb
  20. 12
      spec/fixtures/exports/sales_log_26_27.xml
  21. 18
      spec/fixtures/files/2026_27_sales_bulk_upload.csv
  22. 6
      spec/fixtures/files/sales_logs_csv_export_codes_26.csv
  23. 6
      spec/fixtures/files/sales_logs_csv_export_labels_26.csv
  24. 6
      spec/fixtures/files/sales_logs_csv_export_non_support_codes_26.csv
  25. 6
      spec/fixtures/files/sales_logs_csv_export_non_support_labels_26.csv
  26. 12
      spec/fixtures/variable_definitions/sales_download_26_27.csv
  27. 2
      spec/lib/tasks/log_variable_definitions_spec.rb
  28. 31
      spec/models/form/sales/pages/buyer1_gender_same_as_sex_spec.rb
  29. 40
      spec/models/form/sales/pages/buyer2_gender_same_as_sex_spec.rb
  30. 105
      spec/models/form/sales/pages/person_gender_same_as_sex_spec.rb
  31. 163
      spec/models/form/sales/questions/gender_description_spec.rb
  32. 189
      spec/models/form/sales/questions/gender_same_as_sex_spec.rb
  33. 7
      spec/models/form/sales/subsections/household_characteristics_spec.rb
  34. 5
      spec/services/bulk_upload/sales/year2026/row_parser_spec.rb
  35. 8
      spec/services/csv/sales_log_csv_service_spec.rb

15
app/helpers/bulk_upload/sales_log_to_csv.rb

@ -664,10 +664,23 @@ class BulkUpload::SalesLogToCsv
log.mortlen,
log.extrabor,
log.deposit, # 120
log.mscharge,
log.buildheightclass,
log.gender_same_as_sex1,
log.gender_description1,
log.gender_same_as_sex2,
log.gender_description2,
log.gender_same_as_sex3,
log.gender_description3,
log.gender_same_as_sex4,
log.gender_description4, # 130
log.gender_same_as_sex5,
log.gender_description5,
log.gender_same_as_sex6,
log.gender_description6,
log.hasservicechargeschanged,
log.newservicecharges, # 124
log.newservicecharges, # 136
]
end

12
app/models/derived_variables/lettings_log_variables.rb

@ -450,18 +450,6 @@ private
3 if rent_type == 5
end
def clear_gender_description_unless_gender_not_same_as_sex!
# we do this as the gender same as sex page always contains the gender description box that's hidden
# default submit will send a "" for gender description. this ensure it's nil in this case
# as well as blanking it if the user writes it in mistakenly in bulk upload
(1..8).each do |person_index|
gender_same_as_sex = public_send("gender_same_as_sex#{person_index}")
if gender_same_as_sex.present? && gender_same_as_sex != 2
self["gender_description#{person_index}"] = nil
end
end
end
def set_checkbox_values!
form.questions.select { |q| q.type == "checkbox" }.each do |question|
options = question.answer_keys_without_dividers

2
app/models/derived_variables/sales_log_variables.rb

@ -102,6 +102,8 @@ module DerivedVariables::SalesLogVariables
self.mortlen_known = 0
end
clear_gender_description_unless_gender_not_same_as_sex! if form.start_year_2026_or_later?
set_encoded_derived_values!(DEPENDENCIES)
end

21
app/models/form/sales/pages/buyer1_gender_same_as_sex.rb

@ -0,0 +1,21 @@
class Form::Sales::Pages::Buyer1GenderSameAsSex < ::Form::Page
def initialize(id, hsh, subsection)
super
@id = "buyer_1_gender_same_as_sex"
@depends_on = [
{
"buyer_has_seen_privacy_notice?" => true,
},
{
"buyer_not_interviewed?" => true,
},
]
end
def questions
@questions ||= [
Form::Sales::Questions::GenderSameAsSex.new(nil, nil, self, person_index: 1, buyer: true),
Form::Sales::Questions::GenderDescription.new(nil, nil, self, person_index: 1),
]
end
end

23
app/models/form/sales/pages/buyer2_gender_same_as_sex.rb

@ -0,0 +1,23 @@
class Form::Sales::Pages::Buyer2GenderSameAsSex < ::Form::Page
def initialize(id, hsh, subsection)
super
@id = "buyer_2_gender_same_as_sex"
@depends_on = [
{
"joint_purchase?" => true,
"buyer_has_seen_privacy_notice?" => true,
},
{
"joint_purchase?" => true,
"buyer_not_interviewed?" => true,
},
]
end
def questions
@questions ||= [
Form::Sales::Questions::GenderSameAsSex.new(nil, nil, self, person_index: 2, buyer: true),
Form::Sales::Questions::GenderDescription.new(nil, nil, self, person_index: 2),
]
end
end

16
app/models/form/sales/pages/person_gender_same_as_sex.rb

@ -0,0 +1,16 @@
class Form::Sales::Pages::PersonGenderSameAsSex < ::Form::Page
def initialize(id, hsh, subsection, person_index:)
super(id, hsh, subsection)
@person_index = person_index
@depends_on = [
{ "details_known_#{person_index}" => 1 },
]
end
def questions
@questions ||= [
Form::Sales::Questions::GenderSameAsSex.new(nil, nil, self, person_index: @person_index),
Form::Sales::Questions::GenderDescription.new(nil, nil, self, person_index: @person_index),
]
end
end

16
app/models/form/sales/questions/gender_description.rb

@ -0,0 +1,16 @@
class Form::Sales::Questions::GenderDescription < ::Form::Question
def initialize(id, hsh, page, person_index:)
super(id, hsh, page)
@id = "gender_description#{person_index}"
@type = "text"
@check_answers_card_number = person_index
@person_index = person_index
@question_number = QUESTION_NUMBER_FROM_YEAR[form.start_date.year] || QUESTION_NUMBER_FROM_YEAR[QUESTION_NUMBER_FROM_YEAR.keys.max]
end
QUESTION_NUMBER_FROM_YEAR = { 2026 => 0 }.freeze
def derived?(log)
log.public_send("gender_same_as_sex#{@person_index}") != 2
end
end

33
app/models/form/sales/questions/gender_same_as_sex.rb

@ -0,0 +1,33 @@
class Form::Sales::Questions::GenderSameAsSex < ::Form::Question
def initialize(id, hsh, page, person_index:, buyer: false)
super(id, hsh, page)
@id = "gender_same_as_sex#{person_index}"
@type = "radio"
@check_answers_card_number = person_index
@conditional_for = { "gender_description#{person_index}" => [2] }
@inferred_check_answers_value = [{ "condition" => { "gender_same_as_sex#{person_index}" => 2 }, "value" => "No" }]
@person_index = person_index
@buyer = buyer
@copy_key = "sales.household_characteristics.gender_same_as_sex#{person_index}.#{buyer ? 'buyer' : 'person'}" if person_index == 2
@question_number = QUESTION_NUMBER_FROM_YEAR[form.start_date.year] || QUESTION_NUMBER_FROM_YEAR[QUESTION_NUMBER_FROM_YEAR.keys.max]
end
QUESTION_NUMBER_FROM_YEAR = { 2026 => 0 }.freeze
def answer_options
{
"1" => { "value" => "Yes" },
"2" => { "value" => "No, enter gender identity" },
"divider" => { "value" => true },
"3" => { "value" => "#{@buyer ? 'Buyer' : 'Person'} prefers not to say" },
}.freeze
end
def label_from_value(value, _log = nil, _user = nil)
return unless value
return "Prefers not to say" if value == 3
super
end
end

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

@ -25,6 +25,7 @@ class Form::Sales::Subsections::HouseholdCharacteristics < ::Form::Subsection
Form::Sales::Pages::OldPersonsSharedOwnershipValueCheck.new("age_1_old_persons_shared_ownership_joint_purchase_value_check", nil, self, joint_purchase: true),
Form::Sales::Pages::OldPersonsSharedOwnershipValueCheck.new("age_1_old_persons_shared_ownership_value_check", nil, self, joint_purchase: false),
(Form::Sales::Pages::SexRegisteredAtBirth1.new(nil, nil, self) if form.start_year_2026_or_later?),
(Form::Sales::Pages::Buyer1GenderSameAsSex.new(nil, nil, self) if form.start_year_2026_or_later?),
(Form::Sales::Pages::GenderIdentity1.new(nil, nil, self) unless form.start_year_2026_or_later?),
Form::Sales::Pages::Buyer1EthnicGroup.new(nil, nil, self),
Form::Sales::Pages::Buyer1EthnicBackgroundBlack.new(nil, nil, self),
@ -48,6 +49,7 @@ class Form::Sales::Subsections::HouseholdCharacteristics < ::Form::Subsection
(Form::Sales::Pages::NotRetiredValueCheck.new("age_2_buyer_not_retired_value_check", nil, self, person_index: 2) if form.start_year_2024_or_later?),
(Form::Sales::Pages::PersonStudentNotChildValueCheck.new("buyer_2_age_student_not_child_value_check", nil, self, person_index: 2) unless form.start_year_2025_or_later?),
(Form::Sales::Pages::SexRegisteredAtBirth2.new(nil, nil, self) if form.start_year_2026_or_later?),
(Form::Sales::Pages::Buyer2GenderSameAsSex.new(nil, nil, self) if form.start_year_2026_or_later?),
(Form::Sales::Pages::GenderIdentity2.new(nil, nil, self) unless form.start_year_2026_or_later?),
buyer_2_ethnicity_nationality_pages,
Form::Sales::Pages::Buyer2WorkingSituation.new(nil, nil, self),
@ -77,6 +79,7 @@ class Form::Sales::Subsections::HouseholdCharacteristics < ::Form::Subsection
(Form::Sales::Pages::PartnerUnder16ValueCheck.new("age_#{person_index}_partner_under_16_value_check", nil, self, person_index:) if form.start_year_2024_or_later?),
(Form::Sales::Pages::PersonGenderIdentity.new("person_#{person_index}_gender_identity", nil, self, person_index:) unless form.start_year_2026_or_later?),
(Form::Sales::Pages::PersonSexRegisteredAtBirth.new("person_#{person_index}_sex_registered_at_birth", nil, self, person_index:) if form.start_year_2026_or_later?),
(Form::Sales::Pages::PersonGenderSameAsSex.new("person_#{person_index}_gender_same_as_sex", nil, self, person_index:) if form.start_year_2026_or_later?),
Form::Sales::Pages::PersonWorkingSituation.new("person_#{person_index}_working_situation", nil, self, person_index:),
Form::Sales::Pages::RetirementValueCheck.new("working_situation_#{person_index}_retirement_value_check", nil, self, person_index:),
(Form::Sales::Pages::NotRetiredValueCheck.new("working_situation_#{person_index}_not_retired_value_check", nil, self, person_index:) if form.start_year_2024_or_later?),

13
app/models/log.rb

@ -345,6 +345,19 @@ class Log < ApplicationRecord
end
end
def clear_gender_description_unless_gender_not_same_as_sex!
# we do this as the gender same as sex page always contains the gender description box that's hidden
# default submit will send a "" for gender description. this ensure it's nil in this case
# as well as blanking it if the user writes it in mistakenly in bulk upload
max_person = lettings? ? 8 : 6
(1..max_person).each do |person_index|
gender_same_as_sex = public_send("gender_same_as_sex#{person_index}")
if gender_same_as_sex.present? && gender_same_as_sex != 2
self["gender_description#{person_index}"] = nil
end
end
end
private
# Handle logs that are older than previous collection start date

4
app/services/bulk_upload/sales/year2026/csv_parser.rb

@ -4,7 +4,7 @@ class BulkUpload::Sales::Year2026::CsvParser
include CollectionTimeHelper
# TODO: CLDC-4162: Update when 2026 format is known
FIELDS = 124
FIELDS = 136
FORM_YEAR = 2026
attr_reader :path
@ -27,7 +27,7 @@ class BulkUpload::Sales::Year2026::CsvParser
def cols
# TODO: CLDC-4162: Update when 2026 format is known
@cols ||= ("A".."DT").to_a
@cols ||= ("A".."EF").to_a
end
def row_parsers

77
app/services/bulk_upload/sales/year2026/row_parser.rb

@ -124,6 +124,7 @@ class BulkUpload::Sales::Year2026::RowParser
field_109: "Was a mortgage used for this staircasing transaction?",
field_110: "What was the basic monthly rent prior to staircasing?",
field_111: "What is the basic monthly rent after staircasing?",
field_112: "How long have the buyers been living in the property before the purchase? - Discounted ownership",
field_113: "What was the full purchase price?",
field_114: "What was the amount of any loan, grant, discount or subsidy given?",
@ -136,9 +137,20 @@ class BulkUpload::Sales::Year2026::RowParser
field_121: "What are the total monthly leasehold charges for the property?",
field_122: "What is the building height classification?",
field_123: "Will the service charge change after this staircasing transaction takes place?",
field_124: "What are the new total monthly service charges for the property?",
field_123: "Is the gender buyer 1 identifies with the same as their sex registered at birth?",
field_124: "If 'No', enter buyer 1's gender identity",
field_125: "Is the gender buyer/person 2 identifies with the same as their sex registered at birth?",
field_126: "If 'No', enter buyer/person 2's gender identity",
field_127: "Is the gender person 3 identifies with the same as their sex registered at birth?",
field_128: "If 'No', enter person 3's gender identity",
field_129: "Is the gender person 4 identifies with the same as their sex registered at birth?",
field_130: "If 'No', enter person 4's gender identity",
field_131: "Is the gender person 5 identifies with the same as their sex registered at birth?",
field_132: "If 'No', enter person 5's gender identity",
field_133: "Is the gender person 6 identifies with the same as their sex registered at birth?",
field_134: "If 'No', enter person 6's gender identity",
field_135: "Will the service charge change after this staircasing transaction takes place?",
field_136: "What are the new total monthly service charges for the property?",
}.freeze
ERROR_BASE_KEY = "validations.sales.2026.bulk_upload".freeze
@ -306,7 +318,20 @@ class BulkUpload::Sales::Year2026::RowParser
attribute :field_122, :integer
attribute :field_123, :integer
attribute :field_124, :decimal
attribute :field_124, :string
attribute :field_125, :integer
attribute :field_126, :string
attribute :field_127, :integer
attribute :field_128, :string
attribute :field_129, :integer
attribute :field_130, :string
attribute :field_131, :integer
attribute :field_132, :string
attribute :field_133, :integer
attribute :field_134, :string
attribute :field_135, :integer
attribute :field_136, :decimal
validates :field_1,
presence: {
@ -846,8 +871,21 @@ private
buildheightclass: %i[field_122],
hasservicechargeschanged: %i[field_123],
newservicecharges: %i[field_124],
gender_same_as_sex1: %i[field_123],
gender_description1: %i[field_124],
gender_same_as_sex2: %i[field_125],
gender_description2: %i[field_126],
gender_same_as_sex3: %i[field_127],
gender_description3: %i[field_128],
gender_same_as_sex4: %i[field_129],
gender_description4: %i[field_130],
gender_same_as_sex5: %i[field_131],
gender_description5: %i[field_132],
gender_same_as_sex6: %i[field_133],
gender_description6: %i[field_134],
hasservicechargeschanged: %i[field_135],
newservicecharges: %i[field_136],
}
end
@ -884,8 +922,21 @@ private
attributes["sexrab6"] = field_56
attributes["buildheightclass"] = field_122
attributes["hasservicechargeschanged"] = field_123
attributes["newservicecharges"] = field_124
attributes["gender_same_as_sex1"] = field_123
attributes["gender_description1"] = field_124
attributes["gender_same_as_sex2"] = field_125
attributes["gender_description2"] = field_126
attributes["gender_same_as_sex3"] = field_127
attributes["gender_description3"] = field_128
attributes["gender_same_as_sex4"] = field_129
attributes["gender_description4"] = field_130
attributes["gender_same_as_sex5"] = field_131
attributes["gender_description5"] = field_132
attributes["gender_same_as_sex6"] = field_133
attributes["gender_description6"] = field_134
attributes["hasservicechargeschanged"] = field_135
attributes["newservicecharges"] = field_136
attributes["relat2"] = relationship_from_is_partner(field_34)
attributes["relat3"] = relationship_from_is_partner(field_42)
@ -1087,23 +1138,23 @@ private
end
def person_2_present?
field_35.present? || field_36.present? || field_34.present?
field_35.present? || field_36.present? || field_34.present? || field_125.present? || field_126.present?
end
def person_3_present?
field_43.present? || field_44.present? || field_42.present?
field_43.present? || field_44.present? || field_42.present? || field_127.present? || field_128.present?
end
def person_4_present?
field_47.present? || field_48.present? || field_46.present?
field_47.present? || field_48.present? || field_46.present? || field_129.present? || field_130.present?
end
def person_5_present?
field_51.present? || field_52.present? || field_50.present?
field_51.present? || field_52.present? || field_50.present? || field_131.present? || field_132.present?
end
def person_6_present?
field_55.present? || field_56.present? || field_54.present?
field_55.present? || field_56.present? || field_54.present? || field_133.present? || field_134.present?
end
def relationship_from_is_partner(is_partner)

1
app/services/csv/sales_log_csv_service.rb

@ -123,6 +123,7 @@ module Csv
(2..6).each do |i|
hash["age#{i}"] = { "refused_code" => "-9", "refused_label" => "Not known", "details_known_field" => "details_known_#{i}", "age_known_field" => "age#{i}_known" }
hash["sexrab#{i}"] = { "refused_code" => "R", "refused_label" => "Prefers not to say", "details_known_field" => "details_known_#{i}" }
hash["gender_same_as_sex#{i}"] = { "refused_code" => "3", "refused_label" => "Prefers not to say", "details_known_field" => "details_known_#{i}" }
hash["sex#{i}"] = { "refused_code" => "R", "refused_label" => "Prefers not to say", "details_known_field" => "details_known_#{i}" }
hash["relat#{i}"] = { "refused_code" => "R", "refused_label" => "Prefers not to say", "details_known_field" => "details_known_#{i}" }
hash["ecstat#{i}"] = { "refused_code" => "10", "refused_label" => "Prefers not to say", "details_known_field" => "details_known_#{i}" }

2
app/services/exports/sales_log_export_constants.rb

@ -165,5 +165,7 @@ module Exports::SalesLogExportConstants
(1..6).each do |index|
YEAR_2026_EXPORT_FIELDS << "SEXRAB#{index}"
YEAR_2026_EXPORT_FIELDS << "GENDER_SAME_AS_SEX#{index}"
YEAR_2026_EXPORT_FIELDS << "GENDER_DESCRIPTION#{index}"
end
end

16
config/locales/forms/2026/lettings/household_characteristics.en.yml

@ -32,7 +32,7 @@ en:
gender_same_as_sex1:
page_header: ""
check_answer_label: "Lead tenant’s gender identity same as registered at birth"
check_answer_label: "Lead tenant’s gender identity same as sex registered at birth"
check_answer_prompt: ""
hint_text: ""
question_text: "Is the gender the lead tenant identifies with the same as their sex registered at birth?"
@ -139,7 +139,7 @@ en:
gender_same_as_sex2:
page_header: ""
check_answer_label: "Person 2’s gender identity same as registered at birth"
check_answer_label: "Person 2’s gender identity same as sex registered at birth"
check_answer_prompt: ""
hint_text: ""
question_text: "Is the gender person 2 identifies with the same as their sex registered at birth?"
@ -194,7 +194,7 @@ en:
gender_same_as_sex3:
page_header: ""
check_answer_label: "Person 3’s gender identity same as registered at birth"
check_answer_label: "Person 3’s gender identity same as sex registered at birth"
check_answer_prompt: ""
hint_text: ""
question_text: "Is the gender person 3 identifies with the same as their sex registered at birth?"
@ -249,7 +249,7 @@ en:
gender_same_as_sex4:
page_header: ""
check_answer_label: "Person 4’s gender identity same as registered at birth"
check_answer_label: "Person 4’s gender identity same as sex registered at birth"
check_answer_prompt: ""
hint_text: ""
question_text: "Is the gender person 4 identifies with the same as their sex registered at birth?"
@ -304,7 +304,7 @@ en:
gender_same_as_sex5:
page_header: ""
check_answer_label: "Person 5’s gender identity same as registered at birth"
check_answer_label: "Person 5’s gender identity same as sex registered at birth"
check_answer_prompt: ""
hint_text: ""
question_text: "Is the gender person 5 identifies with the same as their sex registered at birth?"
@ -359,7 +359,7 @@ en:
gender_same_as_sex6:
page_header: ""
check_answer_label: "Person 6’s gender identity same as registered at birth"
check_answer_label: "Person 6’s gender identity same as sex registered at birth"
check_answer_prompt: ""
hint_text: ""
question_text: "Is the gender person 6 identifies with the same as their sex registered at birth?"
@ -414,7 +414,7 @@ en:
gender_same_as_sex7:
page_header: ""
check_answer_label: "Person 7’s gender identity same as registered at birth"
check_answer_label: "Person 7’s gender identity same as sex registered at birth"
check_answer_prompt: ""
hint_text: ""
question_text: "Is the gender person 7 identifies with the same as their sex registered at birth?"
@ -469,7 +469,7 @@ en:
gender_same_as_sex8:
page_header: ""
check_answer_label: "Person 8’s gender identity same as registered at birth"
check_answer_label: "Person 8’s gender identity same as sex registered at birth"
check_answer_prompt: ""
hint_text: ""
question_text: "Is the gender person 8 identifies with the same as their sex registered at birth?"

91
config/locales/forms/2026/sales/household_characteristics.en.yml

@ -23,6 +23,20 @@ en:
hint_text: "This is the sex that was registered at birth. The next question will ask about the buyer's gender identity."
question_text: "What was buyer 1's sex at birth?"
gender_same_as_sex1:
page_header: ""
check_answer_label: "Buyer 1's gender identity same as sex registered at birth"
check_answer_prompt: ""
hint_text: ""
question_text: "Is the gender buyer 1 identifies with the same as their sex registered at birth?"
gender_description1:
page_header: ""
check_answer_label: "Gender identity description"
check_answer_prompt: ""
hint_text: ""
question_text: "Enter gender identity"
ethnic_group:
page_header: ""
check_answer_label: "Buyer 1’s ethnic group"
@ -144,6 +158,27 @@ en:
hint_text: "This is the sex that was registered at birth. The next question will ask about the person's gender identity."
question_text: "What was person 2's sex at birth?"
gender_same_as_sex2:
buyer:
page_header: ""
check_answer_label: "Buyer 2's gender identity same as sex registered at birth"
check_answer_prompt: ""
hint_text: ""
question_text: "Is the gender buyer 2 identifies with the same as their sex registered at birth?"
person:
page_header: ""
check_answer_label: "Person 2's gender identity same as sex registered at birth"
check_answer_prompt: ""
hint_text: ""
question_text: "Is the gender person 2 identifies with the same as their sex registered at birth?"
gender_description2:
page_header: ""
check_answer_label: "Gender identity description"
check_answer_prompt: ""
hint_text: ""
question_text: "Enter gender identity"
ethnic_group2:
page_header: ""
check_answer_label: "Buyer 2’s ethnic group"
@ -273,6 +308,20 @@ en:
hint_text: "This is the sex that was registered at birth. The next question will ask about the person's gender identity."
question_text: "What was person 3's sex at birth?"
gender_same_as_sex3:
page_header: ""
check_answer_label: "Person 3's gender identity same as sex registered at birth"
check_answer_prompt: ""
hint_text: ""
question_text: "Is the gender person 3 identifies with the same as their sex registered at birth?"
gender_description3:
page_header: ""
check_answer_label: "Gender identity description"
check_answer_prompt: ""
hint_text: ""
question_text: "Enter gender identity"
ecstat3:
page_header: ""
check_answer_label: "Person 3’s working situation"
@ -314,6 +363,20 @@ en:
hint_text: "This is the sex that was registered at birth. The next question will ask about the person's gender identity."
question_text: "What was person 4's sex at birth?"
gender_same_as_sex4:
page_header: ""
check_answer_label: "Person 4's gender identity same as sex registered at birth"
check_answer_prompt: ""
hint_text: ""
question_text: "Is the gender person 4 identifies with the same as their sex registered at birth?"
gender_description4:
page_header: ""
check_answer_label: "Gender identity description"
check_answer_prompt: ""
hint_text: ""
question_text: "Enter gender identity"
ecstat4:
page_header: ""
check_answer_label: "Person 4’s working situation"
@ -355,6 +418,20 @@ en:
hint_text: "This is the sex that was registered at birth. The next question will ask about the person's gender identity."
question_text: "What was person 5's sex at birth?"
gender_same_as_sex5:
page_header: ""
check_answer_label: "Person 5's gender identity same as sex registered at birth"
check_answer_prompt: ""
hint_text: ""
question_text: "Is the gender person 5 identifies with the same as their sex registered at birth?"
gender_description5:
page_header: ""
check_answer_label: "Gender identity description"
check_answer_prompt: ""
hint_text: ""
question_text: "Enter gender identity"
ecstat5:
page_header: ""
check_answer_label: "Person 5’s working situation"
@ -396,6 +473,20 @@ en:
hint_text: "This is the sex that was registered at birth. The next question will ask about the person's gender identity."
question_text: "What was person 6's sex at birth?"
gender_same_as_sex6:
page_header: ""
check_answer_label: "Person 6's gender identity same as sex registered at birth"
check_answer_prompt: ""
hint_text: ""
question_text: "Is the gender person 6 identifies with the same as their sex registered at birth?"
gender_description6:
page_header: ""
check_answer_label: "Gender identity description"
check_answer_prompt: ""
hint_text: ""
question_text: "Enter gender identity"
ecstat6:
page_header: ""
check_answer_label: "Person 6’s working situation"

18
db/migrate/20260220141000_add_gender_same_as_sex_fields_to_sales_logs.rb

@ -0,0 +1,18 @@
class AddGenderSameAsSexFieldsToSalesLogs < ActiveRecord::Migration[7.0]
def change
change_table :sales_logs, bulk: true do |t|
t.integer :gender_same_as_sex1
t.integer :gender_same_as_sex2
t.integer :gender_same_as_sex3
t.integer :gender_same_as_sex4
t.integer :gender_same_as_sex5
t.integer :gender_same_as_sex6
t.string :gender_description1
t.string :gender_description2
t.string :gender_description3
t.string :gender_description4
t.string :gender_description5
t.string :gender_description6
end
end
end

12
db/schema.rb

@ -825,6 +825,18 @@ ActiveRecord::Schema[7.2].define(version: 2026_03_05_095832) do
t.string "sexrab5"
t.string "sexrab6"
t.integer "buildheightclass"
t.integer "gender_same_as_sex1"
t.integer "gender_same_as_sex2"
t.integer "gender_same_as_sex3"
t.integer "gender_same_as_sex4"
t.integer "gender_same_as_sex5"
t.integer "gender_same_as_sex6"
t.string "gender_description1"
t.string "gender_description2"
t.string "gender_description3"
t.string "gender_description4"
t.string "gender_description5"
t.string "gender_description6"
t.integer "mortlen_known"
t.integer "hasservicechargeschanged"
t.decimal "newservicecharges", precision: 10, scale: 2

12
spec/factories/sales_log.rb

@ -86,6 +86,7 @@ FactoryBot.define do
age1 { Faker::Number.within(range: 27..45) }
sexrab1 { %w[F M R].sample }
sex1 { %w[F M X R].sample }
gender_same_as_sex1 { 1 }
national { 18 }
buy1livein { 1 }
relat2 { "P" }
@ -98,6 +99,8 @@ FactoryBot.define do
ethnic_group { 17 }
sexrab2 { %w[F M R].sample }
sex2 { "X" }
gender_same_as_sex2 { 2 }
gender_description2 { Faker::Gender.type }
buy2livein { "1" }
ecstat1 { "1" }
ecstat2 { "1" }
@ -131,12 +134,17 @@ FactoryBot.define do
prevshared { 2 }
sexrab3 { %w[F M R].sample }
sex3 { %w[F M X R].sample }
gender_same_as_sex3 { 1 }
sexrab4 { %w[F M R].sample }
sex4 { %w[F M X R].sample }
gender_same_as_sex4 { 2 }
gender_description4 { Faker::Gender.type }
sexrab5 { %w[F M R].sample }
sex5 { %w[F M X R].sample }
gender_same_as_sex5 { 3 }
sexrab6 { %w[F M R].sample }
sex6 { %w[F M X R].sample }
gender_same_as_sex6 { 3 }
mortgage { 20_000 }
ecstat3 { 9 }
ecstat4 { 3 }
@ -291,6 +299,7 @@ FactoryBot.define do
age1 { 27 }
sexrab1 { "F" }
sex1 { "F" }
gender_same_as_sex1 { 1 }
national { 18 }
buy1livein { 1 }
relat2 { "P" }
@ -303,6 +312,8 @@ FactoryBot.define do
ethnic_group { 17 }
sexrab2 { "R" }
sex2 { "X" }
gender_same_as_sex2 { 2 }
gender_description2 { "Non-binary" }
buy2livein { "1" }
ecstat1 { "1" }
ecstat2 { "1" }
@ -311,6 +322,7 @@ FactoryBot.define do
details_known_3 { 1 }
age3_known { 0 }
age3 { 14 }
gender_same_as_sex3 { 3 }
details_known_4 { 1 }
age4_known { 0 }
age4 { 18 }

12
spec/fixtures/exports/sales_log_26_27.xml vendored

@ -89,6 +89,18 @@
<NUMSTAIR/>
<MRENTPRESTAIRCASING/>
<BUILDHEIGHTCLASS>2</BUILDHEIGHTCLASS>
<GENDER_SAME_AS_SEX1>1</GENDER_SAME_AS_SEX1>
<GENDER_DESCRIPTION1/>
<GENDER_SAME_AS_SEX2>2</GENDER_SAME_AS_SEX2>
<GENDER_DESCRIPTION2>Non-binary</GENDER_DESCRIPTION2>
<GENDER_SAME_AS_SEX3>3</GENDER_SAME_AS_SEX3>
<GENDER_DESCRIPTION3/>
<GENDER_SAME_AS_SEX4/>
<GENDER_DESCRIPTION4/>
<GENDER_SAME_AS_SEX5/>
<GENDER_DESCRIPTION5/>
<GENDER_SAME_AS_SEX6/>
<GENDER_DESCRIPTION6/>
<DAY>1</DAY>
<MONTH>4</MONTH>
<YEAR>2026</YEAR>

18
spec/fixtures/files/2026_27_sales_bulk_upload.csv vendored

File diff suppressed because one or more lines are too long

6
spec/fixtures/files/sales_logs_csv_export_codes_26.csv vendored

File diff suppressed because one or more lines are too long

6
spec/fixtures/files/sales_logs_csv_export_labels_26.csv vendored

File diff suppressed because one or more lines are too long

6
spec/fixtures/files/sales_logs_csv_export_non_support_codes_26.csv vendored

File diff suppressed because one or more lines are too long

6
spec/fixtures/files/sales_logs_csv_export_non_support_labels_26.csv vendored

File diff suppressed because one or more lines are too long

12
spec/fixtures/variable_definitions/sales_download_26_27.csv vendored

@ -5,5 +5,17 @@ sexrab4,What was person 4's sex at birth?
sexrab5,What was person 5's sex at birth?
sexrab6,What was person 6's sex at birth?
buildheightclass, What is the building height classification?
gender_same_as_sex1,Is the gender buyer 1 identifies with the same as their sex registered at birth?
gender_description1,If 'No', enter buyer 1's gender identity
gender_same_as_sex2,Is the gender buyer/person 2 identifies with the same as their sex registered at birth?
gender_description2,If 'No', enter buyer/person 2's gender identity
gender_same_as_sex3,Is the gender person 3 identifies with the same as their sex registered at birth?
gender_description3,If 'No', enter person 3's gender identity
gender_same_as_sex4,Is the gender person 4 identifies with the same as their sex registered at birth?
gender_description4,If 'No', enter person 4's gender identity
gender_same_as_sex5,Is the gender person 5 identifies with the same as their sex registered at birth?
gender_description5,If 'No', enter person 5's gender identity
gender_same_as_sex6,Is the gender person 6 identifies with the same as their sex registered at birth?
gender_description6,If 'No', enter person 6's gender identity
hasservicechargeschanged,Will the service charge change after this staircasing transaction takes place?
newservicecharges,What are the new total monthly service charges for the property?

1 sexrab1 sexrab1,What was buyer 1's sex at birth? What was buyer 1's sex at birth?
5 sexrab5 sexrab5,What was person 5's sex at birth? What was person 5's sex at birth?
6 sexrab6 sexrab6,What was person 6's sex at birth? What was person 6's sex at birth?
7 buildheightclass buildheightclass, What is the building height classification? What is the building height classification?
8 gender_same_as_sex1,Is the gender buyer 1 identifies with the same as their sex registered at birth?
9 gender_description1,If 'No', enter buyer 1's gender identity
10 gender_same_as_sex2,Is the gender buyer/person 2 identifies with the same as their sex registered at birth?
11 gender_description2,If 'No', enter buyer/person 2's gender identity
12 gender_same_as_sex3,Is the gender person 3 identifies with the same as their sex registered at birth?
13 gender_description3,If 'No', enter person 3's gender identity
14 gender_same_as_sex4,Is the gender person 4 identifies with the same as their sex registered at birth?
15 gender_description4,If 'No', enter person 4's gender identity
16 gender_same_as_sex5,Is the gender person 5 identifies with the same as their sex registered at birth?
17 gender_description5,If 'No', enter person 5's gender identity
18 gender_same_as_sex6,Is the gender person 6 identifies with the same as their sex registered at birth?
19 gender_description6,If 'No', enter person 6's gender identity
20 hasservicechargeschanged hasservicechargeschanged,Will the service charge change after this staircasing transaction takes place? Will the service charge change after this staircasing transaction takes place?
21 newservicecharges newservicecharges,What are the new total monthly service charges for the property? What are the new total monthly service charges for the property?

2
spec/lib/tasks/log_variable_definitions_spec.rb

@ -6,7 +6,7 @@ RSpec.describe "log_variable_definitions" do
subject(:task) { Rake::Task["data_import:add_variable_definitions"] }
let(:path) { "spec/fixtures/variable_definitions" }
let(:total_variable_definitions_count) { 453 }
let(:total_variable_definitions_count) { 465 }
before do
Rake.application.rake_require("tasks/log_variable_definitions")

31
spec/models/form/sales/pages/buyer1_gender_same_as_sex_spec.rb

@ -0,0 +1,31 @@
require "rails_helper"
RSpec.describe Form::Sales::Pages::Buyer1GenderSameAsSex, type: :model do
include CollectionTimeHelper
subject(:page) { described_class.new(page_id, page_definition, subsection) }
let(:page_id) { nil }
let(:page_definition) { nil }
let(:subsection) { instance_double(Form::Subsection, form: instance_double(Form, start_date: current_collection_start_date)) }
it "has correct subsection" do
expect(page.subsection).to eq(subsection)
end
it "has correct questions" do
expect(page.questions.map(&:id)).to eq(%w[gender_same_as_sex1 gender_description1])
end
it "has the correct id" do
expect(page.id).to eq("buyer_1_gender_same_as_sex")
end
it "has the correct description" do
expect(page.description).to be_nil
end
it "has correct depends_on" do
expect(page.depends_on).to eq([{ "buyer_has_seen_privacy_notice?" => true }, { "buyer_not_interviewed?" => true }])
end
end

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

@ -0,0 +1,40 @@
require "rails_helper"
RSpec.describe Form::Sales::Pages::Buyer2GenderSameAsSex, type: :model do
include CollectionTimeHelper
subject(:page) { described_class.new(page_id, page_definition, subsection) }
let(:page_id) { nil }
let(:page_definition) { nil }
let(:subsection) { instance_double(Form::Subsection, form: instance_double(Form, start_date: current_collection_start_date)) }
it "has correct subsection" do
expect(page.subsection).to eq(subsection)
end
it "has correct questions" do
expect(page.questions.map(&:id)).to eq(%w[gender_same_as_sex2 gender_description2])
end
it "has the correct id" do
expect(page.id).to eq("buyer_2_gender_same_as_sex")
end
it "has the correct description" do
expect(page.description).to be_nil
end
it "has correct depends_on" do
expect(page.depends_on).to eq([
{
"joint_purchase?" => true,
"buyer_has_seen_privacy_notice?" => true,
},
{
"joint_purchase?" => true,
"buyer_not_interviewed?" => true,
},
])
end
end

105
spec/models/form/sales/pages/person_gender_same_as_sex_spec.rb

@ -0,0 +1,105 @@
require "rails_helper"
RSpec.describe Form::Sales::Pages::PersonGenderSameAsSex, type: :model do
include CollectionTimeHelper
subject(:page) { described_class.new(page_id, page_definition, subsection, person_index:) }
let(:page_definition) { nil }
let(:subsection) { instance_double(Form::Subsection, form: instance_double(Form, start_date: current_collection_start_date)) }
let(:person_index) { 2 }
let(:page_id) { "person_2_gender_same_as_sex" }
it "has correct subsection" do
expect(page.subsection).to eq(subsection)
end
it "has the correct description" do
expect(page.description).to be_nil
end
context "with person 2" do
let(:person_index) { 2 }
let(:page_id) { "person_2_gender_same_as_sex" }
it "has correct questions" do
expect(page.questions.map(&:id)).to eq(%w[gender_same_as_sex2 gender_description2])
end
it "has the correct id" do
expect(page.id).to eq("person_2_gender_same_as_sex")
end
it "has correct depends_on" do
expect(page.depends_on).to eq([{ "details_known_2" => 1 }])
end
end
context "with person 3" do
let(:person_index) { 3 }
let(:page_id) { "person_3_gender_same_as_sex" }
it "has correct questions" do
expect(page.questions.map(&:id)).to eq(%w[gender_same_as_sex3 gender_description3])
end
it "has the correct id" do
expect(page.id).to eq("person_3_gender_same_as_sex")
end
it "has correct depends_on" do
expect(page.depends_on).to eq([{ "details_known_3" => 1 }])
end
end
context "with person 4" do
let(:person_index) { 4 }
let(:page_id) { "person_4_gender_same_as_sex" }
it "has correct questions" do
expect(page.questions.map(&:id)).to eq(%w[gender_same_as_sex4 gender_description4])
end
it "has the correct id" do
expect(page.id).to eq("person_4_gender_same_as_sex")
end
it "has correct depends_on" do
expect(page.depends_on).to eq([{ "details_known_4" => 1 }])
end
end
context "with person 5" do
let(:person_index) { 5 }
let(:page_id) { "person_5_gender_same_as_sex" }
it "has correct questions" do
expect(page.questions.map(&:id)).to eq(%w[gender_same_as_sex5 gender_description5])
end
it "has the correct id" do
expect(page.id).to eq("person_5_gender_same_as_sex")
end
it "has correct depends_on" do
expect(page.depends_on).to eq([{ "details_known_5" => 1 }])
end
end
context "with person 6" do
let(:person_index) { 6 }
let(:page_id) { "person_6_gender_same_as_sex" }
it "has correct questions" do
expect(page.questions.map(&:id)).to eq(%w[gender_same_as_sex6 gender_description6])
end
it "has the correct id" do
expect(page.id).to eq("person_6_gender_same_as_sex")
end
it "has correct depends_on" do
expect(page.depends_on).to eq([{ "details_known_6" => 1 }])
end
end
end

163
spec/models/form/sales/questions/gender_description_spec.rb

@ -0,0 +1,163 @@
require "rails_helper"
RSpec.describe Form::Sales::Questions::GenderDescription, type: :model do
include CollectionTimeHelper
subject(:question) { described_class.new(question_id, question_definition, page, person_index:) }
let(:question_id) { nil }
let(:question_definition) { nil }
let(:page) { instance_double(Form::Page) }
let(:person_index) { 2 }
let(:subsection) { instance_double(Form::Subsection) }
let(:form) { instance_double(Form, start_date: current_collection_start_date) }
before do
allow(page).to receive(:subsection).and_return(subsection)
allow(subsection).to receive(:form).and_return(form)
end
it "has correct page" do
expect(question.page).to eq(page)
end
it "has the correct type" do
expect(question.type).to eq("text")
end
context "when person 1" do
let(:person_index) { 1 }
it "has the correct id" do
expect(question.id).to eq("gender_description1")
end
it "has expected check answers card number" do
expect(question.check_answers_card_number).to eq(1)
end
it "has the correct inferred_check_answers_value" do
expect(question.inferred_check_answers_value).to be_nil
end
context "when gender_same_as_sex1 is 'Yes'" do
let(:log) { build(:sales_log, gender_same_as_sex1: 1) }
it "is marked as derived" do
expect(question.derived?(log)).to be true
end
end
context "when gender_same_as_sex1 is 'No'" do
let(:log) { build(:sales_log, gender_same_as_sex1: 2) }
it "is not marked as derived" do
expect(question.derived?(log)).to be false
end
end
context "when gender_same_as_sex1 is 'Prefers not to say'" do
let(:log) { build(:sales_log, gender_same_as_sex1: 3) }
it "is marked as derived" do
expect(question.derived?(log)).to be true
end
end
end
context "when person 2" do
let(:person_index) { 2 }
it "has the correct id" do
expect(question.id).to eq("gender_description2")
end
it "has expected check answers card number" do
expect(question.check_answers_card_number).to eq(2)
end
it "has the correct inferred_check_answers_value" do
expect(question.inferred_check_answers_value).to be_nil
end
context "when gender_same_as_sex2 is 'Yes'" do
let(:log) { build(:sales_log, gender_same_as_sex2: 1) }
it "is marked as derived" do
expect(question.derived?(log)).to be true
end
end
context "when gender_same_as_sex2 is 'No'" do
let(:log) { build(:sales_log, gender_same_as_sex2: 2) }
it "is not marked as derived" do
expect(question.derived?(log)).to be false
end
end
end
context "when person 3" do
let(:person_index) { 3 }
it "has the correct id" do
expect(question.id).to eq("gender_description3")
end
it "has expected check answers card number" do
expect(question.check_answers_card_number).to eq(3)
end
it "has the correct inferred_check_answers_value" do
expect(question.inferred_check_answers_value).to be_nil
end
end
context "when person 4" do
let(:person_index) { 4 }
it "has the correct id" do
expect(question.id).to eq("gender_description4")
end
it "has expected check answers card number" do
expect(question.check_answers_card_number).to eq(4)
end
it "has the correct inferred_check_answers_value" do
expect(question.inferred_check_answers_value).to be_nil
end
end
context "when person 5" do
let(:person_index) { 5 }
it "has the correct id" do
expect(question.id).to eq("gender_description5")
end
it "has expected check answers card number" do
expect(question.check_answers_card_number).to eq(5)
end
it "has the correct inferred_check_answers_value" do
expect(question.inferred_check_answers_value).to be_nil
end
end
context "when person 6" do
let(:person_index) { 6 }
it "has the correct id" do
expect(question.id).to eq("gender_description6")
end
it "has expected check answers card number" do
expect(question.check_answers_card_number).to eq(6)
end
it "has the correct inferred_check_answers_value" do
expect(question.inferred_check_answers_value).to be_nil
end
end
end

189
spec/models/form/sales/questions/gender_same_as_sex_spec.rb

@ -0,0 +1,189 @@
require "rails_helper"
RSpec.describe Form::Sales::Questions::GenderSameAsSex, type: :model do
include CollectionTimeHelper
subject(:question) { described_class.new(question_id, question_definition, page, person_index:) }
let(:question_id) { nil }
let(:question_definition) { nil }
let(:page) { instance_double(Form::Page) }
let(:person_index) { 2 }
let(:subsection) { instance_double(Form::Subsection) }
let(:form) { instance_double(Form, start_date: current_collection_start_date) }
before do
allow(page).to receive(:subsection).and_return(subsection)
allow(subsection).to receive(:form).and_return(form)
end
it "has correct page" do
expect(question.page).to eq(page)
end
it "has the correct type" do
expect(question.type).to eq("radio")
end
it "is not marked as derived" do
expect(question.derived?(nil)).to be false
end
context "when buyer is false (default)" do
it "has the correct answer_options" do
expect(question.answer_options).to eq({
"1" => { "value" => "Yes" },
"2" => { "value" => "No, enter gender identity" },
"divider" => { "value" => true },
"3" => { "value" => "Person prefers not to say" },
})
end
end
context "when buyer is true" do
subject(:question) { described_class.new(question_id, question_definition, page, person_index:, buyer: true) }
it "has the correct answer_options" do
expect(question.answer_options).to eq({
"1" => { "value" => "Yes" },
"2" => { "value" => "No, enter gender identity" },
"divider" => { "value" => true },
"3" => { "value" => "Buyer prefers not to say" },
})
end
end
it "returns correct label_from_value for 'Prefers not to say'" do
expect(question.label_from_value(3)).to eq("Prefers not to say")
end
it "returns nil label_from_value for nil" do
expect(question.label_from_value(nil)).to be_nil
end
context "when person 1 (buyer)" do
subject(:question) { described_class.new(question_id, question_definition, page, person_index: 1, buyer: true) }
let(:person_index) { 1 }
it "has the correct id" do
expect(question.id).to eq("gender_same_as_sex1")
end
it "has expected check answers card number" do
expect(question.check_answers_card_number).to eq(1)
end
it "has the correct conditional_for" do
expect(question.conditional_for).to eq({ "gender_description1" => [2] })
end
it "has the correct inferred_check_answers_value" do
expect(question.inferred_check_answers_value).to eq([{ "condition" => { "gender_same_as_sex1" => 2 }, "value" => "No" }])
end
it "has the correct answer_options with Buyer label" do
expect(question.answer_options["3"]).to eq({ "value" => "Buyer prefers not to say" })
end
end
context "when person 2" do
let(:person_index) { 2 }
it "has the correct id" do
expect(question.id).to eq("gender_same_as_sex2")
end
it "has expected check answers card number" do
expect(question.check_answers_card_number).to eq(2)
end
it "has the correct conditional_for" do
expect(question.conditional_for).to eq({ "gender_description2" => [2] })
end
it "has the correct inferred_check_answers_value" do
expect(question.inferred_check_answers_value).to eq([{ "condition" => { "gender_same_as_sex2" => 2 }, "value" => "No" }])
end
end
context "when person 3" do
let(:person_index) { 3 }
it "has the correct id" do
expect(question.id).to eq("gender_same_as_sex3")
end
it "has expected check answers card number" do
expect(question.check_answers_card_number).to eq(3)
end
it "has the correct conditional_for" do
expect(question.conditional_for).to eq({ "gender_description3" => [2] })
end
it "has the correct inferred_check_answers_value" do
expect(question.inferred_check_answers_value).to eq([{ "condition" => { "gender_same_as_sex3" => 2 }, "value" => "No" }])
end
end
context "when person 4" do
let(:person_index) { 4 }
it "has the correct id" do
expect(question.id).to eq("gender_same_as_sex4")
end
it "has expected check answers card number" do
expect(question.check_answers_card_number).to eq(4)
end
it "has the correct conditional_for" do
expect(question.conditional_for).to eq({ "gender_description4" => [2] })
end
it "has the correct inferred_check_answers_value" do
expect(question.inferred_check_answers_value).to eq([{ "condition" => { "gender_same_as_sex4" => 2 }, "value" => "No" }])
end
end
context "when person 5" do
let(:person_index) { 5 }
it "has the correct id" do
expect(question.id).to eq("gender_same_as_sex5")
end
it "has expected check answers card number" do
expect(question.check_answers_card_number).to eq(5)
end
it "has the correct conditional_for" do
expect(question.conditional_for).to eq({ "gender_description5" => [2] })
end
it "has the correct inferred_check_answers_value" do
expect(question.inferred_check_answers_value).to eq([{ "condition" => { "gender_same_as_sex5" => 2 }, "value" => "No" }])
end
end
context "when person 6" do
let(:person_index) { 6 }
it "has the correct id" do
expect(question.id).to eq("gender_same_as_sex6")
end
it "has expected check answers card number" do
expect(question.check_answers_card_number).to eq(6)
end
it "has the correct conditional_for" do
expect(question.conditional_for).to eq({ "gender_description6" => [2] })
end
it "has the correct inferred_check_answers_value" do
expect(question.inferred_check_answers_value).to eq([{ "condition" => { "gender_same_as_sex6" => 2 }, "value" => "No" }])
end
end
end

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

@ -407,6 +407,7 @@ RSpec.describe Form::Sales::Subsections::HouseholdCharacteristics, type: :model
age_1_old_persons_shared_ownership_joint_purchase_value_check
age_1_old_persons_shared_ownership_value_check
buyer_1_sex_registered_at_birth
buyer_1_gender_same_as_sex
buyer_1_ethnic_group
buyer_1_ethnic_background_black
buyer_1_ethnic_background_asian
@ -427,6 +428,7 @@ RSpec.describe Form::Sales::Subsections::HouseholdCharacteristics, type: :model
age_2_buyer_retirement_value_check
age_2_buyer_not_retired_value_check
buyer_2_sex_registered_at_birth
buyer_2_gender_same_as_sex
buyer_2_ethnic_group
buyer_2_ethnic_background_black
buyer_2_ethnic_background_asian
@ -451,6 +453,7 @@ RSpec.describe Form::Sales::Subsections::HouseholdCharacteristics, type: :model
age_2_not_retired_value_check
age_2_partner_under_16_value_check
person_2_sex_registered_at_birth
person_2_gender_same_as_sex
person_2_working_situation
working_situation_2_retirement_value_check
working_situation_2_not_retired_value_check
@ -463,6 +466,7 @@ RSpec.describe Form::Sales::Subsections::HouseholdCharacteristics, type: :model
age_3_not_retired_value_check
age_3_partner_under_16_value_check
person_3_sex_registered_at_birth
person_3_gender_same_as_sex
person_3_working_situation
working_situation_3_retirement_value_check
working_situation_3_not_retired_value_check
@ -475,6 +479,7 @@ RSpec.describe Form::Sales::Subsections::HouseholdCharacteristics, type: :model
age_4_not_retired_value_check
age_4_partner_under_16_value_check
person_4_sex_registered_at_birth
person_4_gender_same_as_sex
person_4_working_situation
working_situation_4_retirement_value_check
working_situation_4_not_retired_value_check
@ -487,6 +492,7 @@ RSpec.describe Form::Sales::Subsections::HouseholdCharacteristics, type: :model
age_5_not_retired_value_check
age_5_partner_under_16_value_check
person_5_sex_registered_at_birth
person_5_gender_same_as_sex
person_5_working_situation
working_situation_5_retirement_value_check
working_situation_5_not_retired_value_check
@ -499,6 +505,7 @@ RSpec.describe Form::Sales::Subsections::HouseholdCharacteristics, type: :model
age_6_not_retired_value_check
age_6_partner_under_16_value_check
person_6_sex_registered_at_birth
person_6_gender_same_as_sex
person_6_working_situation
working_situation_6_retirement_value_check
working_situation_6_not_retired_value_check

5
spec/services/bulk_upload/sales/year2026/row_parser_spec.rb

@ -114,7 +114,10 @@ RSpec.describe BulkUpload::Sales::Year2026::RowParser do
field_110: "900",
field_122: "1",
field_123: "1",
field_124: "150",
field_125: "2",
field_126: "Non-binary",
field_135: "1",
field_136: "150",
}
end

8
spec/services/csv/sales_log_csv_service_spec.rb

@ -38,6 +38,14 @@ RSpec.describe Csv::SalesLogCsvService do
age6: nil,
ecstat6: nil,
relat6: nil,
gender_same_as_sex1: 1,
gender_same_as_sex2: 2,
gender_description2: "Nonbinary",
gender_same_as_sex3: 1,
gender_same_as_sex4: 2,
gender_description4: "Genderfluid",
gender_same_as_sex5: 3,
gender_same_as_sex6: nil,
sexrab6: nil,
sex6: nil,
town_or_city: "Town or city",

Loading…
Cancel
Save