From 3f4c1fde50c530f3741587fb9e6c059934fe3b06 Mon Sep 17 00:00:00 2001 From: samyou-softwire Date: Tue, 10 Mar 2026 09:56:09 +0000 Subject: [PATCH] CLDC-4204: Renumber fields to match spec --- .../bulk_upload/sales/year2026/csv_parser.rb | 4 +- .../bulk_upload/sales/year2026/row_parser.rb | 1035 ++++++++--------- .../sales/year2026/csv_parser_spec.rb | 2 +- .../sales/year2026/row_parser_spec.rb | 504 ++++---- 4 files changed, 770 insertions(+), 775 deletions(-) diff --git a/app/services/bulk_upload/sales/year2026/csv_parser.rb b/app/services/bulk_upload/sales/year2026/csv_parser.rb index efe89d1e8..9101959c1 100644 --- a/app/services/bulk_upload/sales/year2026/csv_parser.rb +++ b/app/services/bulk_upload/sales/year2026/csv_parser.rb @@ -3,7 +3,6 @@ require "csv" class BulkUpload::Sales::Year2026::CsvParser include CollectionTimeHelper - # TODO: CLDC-4162: Update when 2026 format is known FIELDS = 136 FORM_YEAR = 2026 @@ -26,8 +25,7 @@ class BulkUpload::Sales::Year2026::CsvParser end def cols - # TODO: CLDC-4162: Update when 2026 format is known - @cols ||= ("A".."EF").to_a + @cols ||= ("A".."EG").to_a end def row_parsers diff --git a/app/services/bulk_upload/sales/year2026/row_parser.rb b/app/services/bulk_upload/sales/year2026/row_parser.rb index 94f1a9ae6..cb9eea1ae 100644 --- a/app/services/bulk_upload/sales/year2026/row_parser.rb +++ b/app/services/bulk_upload/sales/year2026/row_parser.rb @@ -30,154 +30,153 @@ class BulkUpload::Sales::Year2026::RowParser field_22: "Part 2 of postcode of property", field_23: "What is the local authority of the property?", field_24: "What type of unit is the property?", - field_25: "How many bedrooms does the property have?", - field_26: "Which type of building is the property?", - field_27: "Is the property built or adapted to wheelchair user standards?", - - field_28: "Age of buyer 1", - field_29: "Buyer 1's sex, as registered at birth", - field_30: "What is buyer 1’s ethnic group?", - field_31: "What is buyer 1’s nationality?", - field_32: "Working situation of buyer 1", - field_33: "Will buyer 1 live in the property?", - field_34: "Is buyer 2 or person 2 the partner of buyer 1?", - field_35: "Age of person 2", - field_36: "Buyer/Person 2's sex, as registered at birth", - field_37: "Which of the following best describes buyer 2’s ethnic background?", - field_38: "What is buyer 2’s nationality?", - field_39: "What is buyer 2 or person 2’s working situation?", - field_40: "Will buyer 2 live in the property?", - field_41: "Besides the buyers, how many people will live in the property?", - - field_42: "Is person 3 the partner of buyer 1?", - field_43: "Age of person 3", - field_44: "Person 3's sex, as registered at birth", - field_45: "Working situation of person 3", - field_46: "Is person 4 the partner of buyer 1?", - field_47: "Age of person 4", - field_48: "Person 4's sex, as registered at birth", - field_49: "Working situation of person 4", - field_50: "Is person 5 the partner of buyer 1?", - field_51: "Age of person 5", - field_52: "Person 5's sex, as registered at birth", - field_53: "Working situation of person 5", - field_54: "Is person 6 the partner of buyer 1?", - field_55: "Age of person 6", - field_56: "Person 6's sex, as registered at birth", - field_57: "Working situation of person 6", - - field_58: "What was buyer 1’s previous tenure?", - field_59: "Do you know the postcode of buyer 1’s last settled home?", - field_60: "Part 1 of postcode of buyer 1’s last settled home", - field_61: "Part 2 of postcode of buyer 1’s last settled home", - field_62: "What is the local authority of buyer 1’s last settled home?", - field_63: "At the time of purchase, was buyer 2 living at the same address as buyer 1?", - field_64: "What was buyer 2’s previous tenure?", - - field_65: "Has the buyer ever served in the UK Armed Forces and for how long?", - field_66: "Is the buyer still serving in the UK armed forces?", - field_67: "Are any of the buyers a spouse or civil partner of a UK Armed Forces regular who died in service within the last 2 years?", - field_68: "Does anyone in the household consider themselves to have a disability?", - field_69: "Does anyone in the household use a wheelchair?", - - field_70: "What is buyer 1’s gross annual income?", - field_71: "Was buyer 1’s income used for a mortgage application?", - field_72: "What is buyer 2’s gross annual income?", - field_73: "Was buyer 2’s income used for a mortgage application?", - field_74: "Were the buyers receiving any of these housing-related benefits immediately before buying this property?", - field_75: "What is the total amount the buyers had in savings before they paid any deposit for the property?", - field_76: "Have any of the purchasers previously owned a property?", - field_77: "Was the previous property under shared ownership?", - - field_78: "Is this a resale?", - field_79: "How long have the buyers been living in the property before the purchase? - Shared ownership", - field_80: "What is the day of the practical completion or handover date?", - field_81: "What is the month of the practical completion or handover date?", - field_82: "What is the year of the practical completion or handover date?", - field_83: "How many bedrooms did the buyer’s previous property have?", - field_84: "What was the type of the buyer’s previous property?", - field_85: "What was the rent type of the buyer’s previous property?", - field_86: "What was the full purchase price?", - field_87: "What was the initial percentage share purchased?", - field_88: "Was a mortgage used for the purchase of this property? - Shared ownership", - field_89: "What is the mortgage amount?", - field_90: "What is the length of the mortgage in years? - Shared ownership", - field_91: "How much was the cash deposit paid on the property?", - field_92: "How much cash discount was given through Social Homebuy?", - field_93: "What is the basic monthly rent?", - field_94: "What are the total monthly service charges for the property?", - field_95: "What are the total monthly estate management fees for the property?", - - field_96: "What percentage of the property has been bought in this staircasing transaction?", - field_97: "What percentage of the property does the buyer now own in total?", - field_98: "Was this transaction part of a back-to-back staircasing transaction to facilitate sale of the home on the open market?", - field_99: "Is this the first time the buyer has engaged in staircasing in the home?", - field_100: "What was the day of the initial purchase of a share in the property? DD", - field_101: "What was the month of the initial purchase of a share in the property? MM", - field_102: "What was the year of the initial purchase of a share in the property? YYYY", - field_103: "Including this time, how many times has the shared owner engaged in staircasing in the home?", - field_104: "What was the day of the last staircasing transaction? DD", - field_105: "What was the month of the last staircasing transaction? MM", - field_106: "What was the year of the last staircasing transaction? YYYY", - field_107: "What is the full purchase price for this staircasing transaction?", - field_108: "What was the percentage share purchased in the initial transaction?", - 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?", - field_115: "What was the percentage discount?", - field_116: "Was a mortgage used for the purchase of this property? - Discounted ownership", - field_117: "What is the mortgage amount?", - field_118: "What is the length of the mortgage in years? - Discounted ownership", - field_119: "Does this include any extra borrowing?", - field_120: "How much was the cash deposit paid on the property?", - field_121: "What are the total monthly leasehold charges for the property?", - - field_122: "What is the building height classification?", - 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?", + field_25: "What is the building height classification?", + field_26: "How many bedrooms does the property have?", + field_27: "Which type of building is the property?", + field_28: "Is the property built or adapted to wheelchair user standards?", + + field_29: "Age of buyer 1", + field_30: "Buyer 1's sex, as registered at birth", + field_31: "Is the gender buyer 1 identifies with the same as their sex registered at birth?", + field_32: "If 'No', enter buyer 1's gender identity", + field_33: "What is buyer 1’s ethnic group?", + field_34: "What is buyer 1’s nationality?", + field_35: "Working situation of buyer 1", + field_36: "Will buyer 1 live in the property?", + field_37: "Is buyer 2 or person 2 the partner of buyer 1?", + field_38: "Age of person 2", + field_39: "Buyer/Person 2's sex, as registered at birth", + field_40: "Is the gender buyer/person 2 identifies with the same as their sex registered at birth?", + field_41: "If 'No', enter buyer/person 2's gender identity", + field_42: "Which of the following best describes buyer 2’s ethnic background?", + field_43: "What is buyer 2’s nationality?", + field_44: "What is buyer 2 or person 2’s working situation?", + field_45: "Will buyer 2 live in the property?", + field_46: "Besides the buyers, how many people will live in the property?", + + field_47: "Is person 3 the partner of buyer 1?", + field_48: "Age of person 3", + field_49: "Person 3's sex, as registered at birth", + field_50: "Is the gender person 3 identifies with the same as their sex registered at birth?", + field_51: "If 'No', enter person 3's gender identity", + field_52: "Working situation of person 3", + field_53: "Is person 4 the partner of buyer 1?", + field_54: "Age of person 4", + field_55: "Person 4's sex, as registered at birth", + field_56: "Is the gender person 4 identifies with the same as their sex registered at birth?", + field_57: "If 'No', enter person 4's gender identity", + field_58: "Working situation of person 4", + field_59: "Is person 5 the partner of buyer 1?", + field_60: "Age of person 5", + field_61: "Person 5's sex, as registered at birth", + field_62: "Is the gender person 5 identifies with the same as their sex registered at birth?", + field_63: "If 'No', enter person 5's gender identity", + field_64: "Working situation of person 5", + field_65: "Is person 6 the partner of buyer 1?", + field_66: "Age of person 6", + field_67: "Person 6's sex, as registered at birth", + field_68: "Is the gender person 6 identifies with the same as their sex registered at birth?", + field_69: "If 'No', enter person 6's gender identity", + field_70: "Working situation of person 6", + + field_71: "What was buyer 1’s previous tenure?", + field_72: "Do you know the postcode of buyer 1’s last settled home?", + field_73: "Part 1 of postcode of buyer 1’s last settled home", + field_74: "Part 2 of postcode of buyer 1’s last settled home", + field_75: "What is the local authority of buyer 1’s last settled home?", + field_76: "At the time of purchase, was buyer 2 living at the same address as buyer 1?", + field_77: "What was buyer 2’s previous tenure?", + + field_78: "Has the buyer ever served in the UK Armed Forces and for how long?", + field_79: "Is the buyer still serving in the UK armed forces?", + field_80: "Are any of the buyers a spouse or civil partner of a UK Armed Forces regular who died in service within the last 2 years?", + field_81: "Does anyone in the household consider themselves to have a disability?", + field_82: "Does anyone in the household use a wheelchair?", + + field_83: "What is buyer 1’s gross annual income?", + field_84: "Was buyer 1’s income used for a mortgage application?", + field_85: "What is buyer 2’s gross annual income?", + field_86: "Was buyer 2’s income used for a mortgage application?", + field_87: "Were the buyers receiving any of these housing-related benefits immediately before buying this property?", + field_88: "What is the total amount the buyers had in savings before they paid any deposit for the property?", + field_89: "Have any of the purchasers previously owned a property?", + field_90: "Was the previous property under shared ownership?", + + field_91: "Is this a resale?", + field_92: "How long have the buyers been living in the property before the purchase? - Shared ownership", + field_93: "What is the day of the practical completion or handover date?", + field_94: "What is the month of the practical completion or handover date?", + field_95: "What is the year of the practical completion or handover date?", + field_96: "How many bedrooms did the buyer’s previous property have?", + field_97: "What was the type of the buyer’s previous property?", + field_98: "What was the rent type of the buyer’s previous property?", + field_99: "What was the full purchase price?", + field_100: "What was the initial percentage share purchased?", + field_101: "Was a mortgage used for the purchase of this property? - Shared ownership", + field_102: "What is the mortgage amount?", + field_103: "What is the length of the mortgage in years? - Shared ownership", + field_104: "How much was the cash deposit paid on the property?", + field_105: "How much cash discount was given through Social Homebuy?", + field_106: "What is the basic monthly rent?", + field_107: "What are the total monthly service charges for the property?", + field_108: "What are the total monthly estate management fees for the property?", + + field_109: "What percentage of the property has been bought in this staircasing transaction?", + field_110: "What percentage of the property does the buyer now own in total?", + field_111: "Was this transaction part of a back-to-back staircasing transaction to facilitate sale of the home on the open market?", + field_112: "Is this the first time the buyer has engaged in staircasing in the home?", + field_113: "What was the day of the initial purchase of a share in the property? DD", + field_114: "What was the month of the initial purchase of a share in the property? MM", + field_115: "What was the year of the initial purchase of a share in the property? YYYY", + field_116: "Including this time, how many times has the shared owner engaged in staircasing in the home?", + field_117: "What was the day of the last staircasing transaction? DD", + field_118: "What was the month of the last staircasing transaction? MM", + field_119: "What was the year of the last staircasing transaction? YYYY", + field_120: "What is the full purchase price for this staircasing transaction?", + field_121: "What was the percentage share purchased in the initial transaction?", + field_122: "Was a mortgage used for this staircasing transaction?", + field_123: "What was the basic monthly rent prior to staircasing?", + field_124: "What is the basic monthly rent after staircasing?", + field_125: "Will the service charge change after this staircasing transaction takes place?", + field_126: "What are the new total monthly service charges for the property?", + + field_127: "How long have the buyers been living in the property before the purchase? - Discounted ownership", + field_128: "What was the full purchase price?", + field_129: "What was the amount of any loan, grant, discount or subsidy given?", + field_130: "What was the percentage discount?", + field_131: "Was a mortgage used for the purchase of this property? - Discounted ownership", + field_132: "What is the mortgage amount?", + field_133: "What is the length of the mortgage in years? - Discounted ownership", + field_134: "Does this include any extra borrowing?", + field_135: "How much was the cash deposit paid on the property?", + field_136: "What are the total monthly leasehold charges for the property?", }.freeze ERROR_BASE_KEY = "validations.sales.2026.bulk_upload".freeze CASE_INSENSITIVE_FIELDS = [ - :field_28, # Age of buyer 1 - :field_35, # Age of person 2 - :field_43, # Age of person 3 - :field_47, # Age of person 4 - :field_51, # Age of person 5 - :field_55, # Age of person 6 - - :field_29, # Buyer 1's sex, as registered at birth - :field_36, # Buyer/Person 2's sex, as registered at birth - :field_44, # Person 3's sex, as registered at birth - :field_48, # Person 4's sex, as registered at birth - :field_52, # Person 5's sex, as registered at birth - :field_56, # Person 6's sex, as registered at birth - - :field_64, # What was buyer 2’s previous tenure? - - :field_75, # What is the total amount the buyers had in savings before they paid any deposit for the property? - :field_70, # What is buyer 1’s gross annual income? - :field_72, # What is buyer 2’s gross annual income? - - :field_90, # What is the length of the mortgage in years? - Shared ownership - :field_118, # What is the length of the mortgage in years? - Discounted ownership + :field_29, # Age of buyer 1 + :field_38, # Age of person 2 + :field_48, # Age of person 3 + :field_54, # Age of person 4 + :field_60, # Age of person 5 + :field_66, # Age of person 6 + + :field_30, # Buyer 1's sex, as registered at birth + :field_39, # Buyer/Person 2's sex, as registered at birth + :field_49, # Person 3's sex, as registered at birth + :field_55, # Person 4's sex, as registered at birth + :field_61, # Person 5's sex, as registered at birth + :field_67, # Person 6's sex, as registered at birth + + :field_77, # What was buyer 2’s previous tenure? + + :field_88, # What is the total amount the buyers had in savings before they paid any deposit for the property? + :field_83, # What is buyer 1’s gross annual income? + :field_85, # What is buyer 2’s gross annual income? + + :field_103, # What is the length of the mortgage in years? - Shared ownership + :field_133, # What is the length of the mortgage in years? - Discounted ownership ].freeze attribute :bulk_upload @@ -213,124 +212,122 @@ class BulkUpload::Sales::Year2026::RowParser attribute :field_25, :integer attribute :field_26, :integer attribute :field_27, :integer + attribute :field_28, :integer - attribute :field_28, :string attribute :field_29, :string - attribute :field_30, :integer + attribute :field_30, :string attribute :field_31, :integer - attribute :field_32, :integer + attribute :field_32, :string attribute :field_33, :integer attribute :field_34, :integer - attribute :field_35, :string - attribute :field_36, :string + attribute :field_35, :integer + attribute :field_36, :integer attribute :field_37, :integer - attribute :field_38, :integer - attribute :field_39, :integer + attribute :field_38, :string + attribute :field_39, :string attribute :field_40, :integer - attribute :field_41, :integer - + attribute :field_41, :string attribute :field_42, :integer - attribute :field_43, :string - attribute :field_44, :string + attribute :field_43, :integer + attribute :field_44, :integer attribute :field_45, :integer attribute :field_46, :integer - attribute :field_47, :string + + attribute :field_47, :integer attribute :field_48, :string - attribute :field_49, :integer + attribute :field_49, :string attribute :field_50, :integer attribute :field_51, :string - attribute :field_52, :string + attribute :field_52, :integer attribute :field_53, :integer - attribute :field_54, :integer + attribute :field_54, :string attribute :field_55, :string - attribute :field_56, :string - attribute :field_57, :integer - + attribute :field_56, :integer + attribute :field_57, :string attribute :field_58, :integer attribute :field_59, :integer attribute :field_60, :string attribute :field_61, :string - attribute :field_62, :string - attribute :field_63, :integer - attribute :field_64, :string - + attribute :field_62, :integer + attribute :field_63, :string + attribute :field_64, :integer attribute :field_65, :integer - attribute :field_66, :integer - attribute :field_67, :integer + attribute :field_66, :string + attribute :field_67, :string attribute :field_68, :integer - attribute :field_69, :integer + attribute :field_69, :string + attribute :field_70, :integer - attribute :field_70, :string attribute :field_71, :integer - attribute :field_72, :string - attribute :field_73, :integer - attribute :field_74, :integer + attribute :field_72, :integer + attribute :field_73, :string + attribute :field_74, :string attribute :field_75, :string attribute :field_76, :integer - attribute :field_77, :integer + attribute :field_77, :string attribute :field_78, :integer attribute :field_79, :integer attribute :field_80, :integer attribute :field_81, :integer attribute :field_82, :integer - attribute :field_83, :integer + + attribute :field_83, :string attribute :field_84, :integer - attribute :field_85, :integer - attribute :field_86, :decimal - attribute :field_87, :decimal - attribute :field_88, :integer - attribute :field_89, :decimal - attribute :field_90, :string - attribute :field_91, :decimal - attribute :field_92, :decimal - attribute :field_93, :decimal - attribute :field_94, :decimal - attribute :field_95, :decimal - - attribute :field_96, :decimal - attribute :field_97, :decimal + attribute :field_85, :string + attribute :field_86, :integer + attribute :field_87, :integer + attribute :field_88, :string + attribute :field_89, :integer + attribute :field_90, :integer + + attribute :field_91, :integer + attribute :field_92, :integer + attribute :field_93, :integer + attribute :field_94, :integer + attribute :field_95, :integer + attribute :field_96, :integer + attribute :field_97, :integer attribute :field_98, :integer - attribute :field_99, :integer - attribute :field_100, :integer + attribute :field_99, :decimal + attribute :field_100, :decimal attribute :field_101, :integer - attribute :field_102, :integer - attribute :field_103, :integer - attribute :field_104, :integer - attribute :field_105, :integer - attribute :field_106, :integer + attribute :field_102, :decimal + attribute :field_103, :string + attribute :field_104, :decimal + attribute :field_105, :decimal + attribute :field_106, :decimal attribute :field_107, :decimal attribute :field_108, :decimal - attribute :field_109, :integer - attribute :field_110, :decimal - attribute :field_111, :decimal + attribute :field_109, :decimal + attribute :field_110, :decimal + attribute :field_111, :integer attribute :field_112, :integer - attribute :field_113, :decimal + attribute :field_113, :integer attribute :field_114, :integer - attribute :field_115, :decimal + attribute :field_115, :integer attribute :field_116, :integer - attribute :field_117, :decimal - attribute :field_118, :string + attribute :field_117, :integer + attribute :field_118, :integer attribute :field_119, :integer attribute :field_120, :decimal attribute :field_121, :decimal attribute :field_122, :integer - - attribute :field_123, :integer - attribute :field_124, :string + attribute :field_123, :decimal + attribute :field_124, :decimal attribute :field_125, :integer - attribute :field_126, :string + attribute :field_126, :decimal + attribute :field_127, :integer - attribute :field_128, :string + attribute :field_128, :decimal attribute :field_129, :integer - attribute :field_130, :string + attribute :field_130, :decimal attribute :field_131, :integer - attribute :field_132, :string - attribute :field_133, :integer - attribute :field_134, :string - - attribute :field_135, :integer + attribute :field_132, :decimal + attribute :field_133, :string + attribute :field_134, :integer + attribute :field_135, :decimal attribute :field_136, :decimal validates :field_1, @@ -425,7 +422,7 @@ class BulkUpload::Sales::Year2026::RowParser }, on: :after_log - validates :field_115, + validates :field_130, numericality: { message: I18n.t("#{ERROR_BASE_KEY}.numeric.within_range", field: "Percentage discount", min: "0%", max: "70%"), greater_than_or_equal_to: 0, @@ -451,7 +448,7 @@ class BulkUpload::Sales::Year2026::RowParser }, on: :after_log - validates :field_103, + validates :field_116, numericality: { greater_than_or_equal_to: 2, less_than_or_equal_to: 10, @@ -460,7 +457,7 @@ class BulkUpload::Sales::Year2026::RowParser }, on: :before_log - validates :field_90, + validates :field_103, if: :shared_ownership?, format: { with: /\A(\d+|R)\z/, @@ -468,7 +465,7 @@ class BulkUpload::Sales::Year2026::RowParser }, on: :after_log - validates :field_118, + validates :field_133, if: :discounted_ownership?, format: { with: /\A(\d+|R)\z/, @@ -588,9 +585,9 @@ class BulkUpload::Sales::Year2026::RowParser "field_7", # purchaser_code "field_21", # postcode "field_22", # postcode - "field_28", # age1 - "field_29", # sexrab1 - "field_32", # ecstat1 + "field_29", # age1 + "field_30", # sexrab1 + "field_35", # ecstat1 ) end @@ -610,16 +607,16 @@ private end def prevtenbuy2 - case field_64 + case field_77 when "R" 0 else - field_64 + field_77 end end def infer_buyer2_ethnic_group_from_ethnic - case field_37 + case field_42 when 1, 2, 3, 18, 20 0 when 4, 5, 6, 7 @@ -631,7 +628,7 @@ private when 16, 19 4 else - field_37 + field_42 end end @@ -697,19 +694,19 @@ private end def two_buyers_share_address? - field_63 == 2 + field_76 == 2 end def not_resale? - field_78 == 2 + field_91 == 2 end def buyer_1_previous_tenure_not_1_or_2? - field_58 != 1 && field_58 != 2 + field_71 != 1 && field_71 != 2 end def mortgage_used? - field_88 == 2 + field_101 == 2 end def social_homebuy? @@ -717,11 +714,11 @@ private end def buyers_own_all? - field_97 == 100 + field_110 == 100 end def buyer_staircased_before? - field_99 == 1 + field_112 == 1 end def buyer_interviewed? @@ -737,89 +734,89 @@ private purchid: %i[field_7], saledate: %i[field_1 field_2 field_3], noint: %i[field_14], - age1_known: %i[field_28], - age1: %i[field_28], - age2_known: %i[field_35], - age2: %i[field_35], - age3_known: %i[field_43], - age3: %i[field_43], - age4_known: %i[field_47], - age4: %i[field_47], - age5_known: %i[field_51], - age5: %i[field_51], - age6_known: %i[field_55], - age6: %i[field_55], - relat2: %i[field_34], - relat3: %i[field_42], - relat4: %i[field_46], - relat5: %i[field_50], - relat6: %i[field_54], - - ecstat1: %i[field_32], - ecstat2: %i[field_39], - ecstat3: %i[field_45], - - ecstat4: %i[field_49], - ecstat5: %i[field_53], - ecstat6: %i[field_57], - ethnic_group: %i[field_30], - ethnic: %i[field_30], - nationality_all: %i[field_31], - nationality_all_group: %i[field_31], - income1nk: %i[field_70], - income1: %i[field_70], - income2nk: %i[field_72], - income2: %i[field_72], - inc1mort: %i[field_71], - inc2mort: %i[field_73], - savingsnk: %i[field_75], - savings: %i[field_75], - prevown: %i[field_76], - prevten: %i[field_58], - prevloc: %i[field_62], - previous_la_known: %i[field_62], - ppcodenk: %i[field_59], - ppostcode_full: %i[field_60 field_61], - disabled: %i[field_68], - - wheel: %i[field_69], - beds: %i[field_25], + age1_known: %i[field_29], + age1: %i[field_29], + age2_known: %i[field_38], + age2: %i[field_38], + age3_known: %i[field_48], + age3: %i[field_48], + age4_known: %i[field_54], + age4: %i[field_54], + age5_known: %i[field_60], + age5: %i[field_60], + age6_known: %i[field_66], + age6: %i[field_66], + relat2: %i[field_37], + relat3: %i[field_47], + relat4: %i[field_53], + relat5: %i[field_59], + relat6: %i[field_65], + + ecstat1: %i[field_35], + ecstat2: %i[field_44], + ecstat3: %i[field_52], + + ecstat4: %i[field_58], + ecstat5: %i[field_64], + ecstat6: %i[field_70], + ethnic_group: %i[field_33], + ethnic: %i[field_33], + nationality_all: %i[field_34], + nationality_all_group: %i[field_34], + income1nk: %i[field_83], + income1: %i[field_83], + income2nk: %i[field_85], + income2: %i[field_85], + inc1mort: %i[field_84], + inc2mort: %i[field_86], + savingsnk: %i[field_88], + savings: %i[field_88], + prevown: %i[field_89], + prevten: %i[field_71], + prevloc: %i[field_75], + previous_la_known: %i[field_75], + ppcodenk: %i[field_72], + ppostcode_full: %i[field_73 field_74], + disabled: %i[field_81], + + wheel: %i[field_82], + beds: %i[field_26], proptype: %i[field_24], - builtype: %i[field_26], + builtype: %i[field_27], la_known: %i[field_23], la: %i[field_23], is_la_inferred: %i[field_23], pcodenk: %i[field_21 field_22], postcode_full: %i[field_21 field_22], - wchair: %i[field_27], + wchair: %i[field_28], type: %i[field_9 field_11 field_8], - resale: %i[field_78], - hodate: %i[field_80 field_81 field_82], + resale: %i[field_91], + hodate: %i[field_93 field_94 field_95], - frombeds: %i[field_83], - fromprop: %i[field_84], + frombeds: %i[field_96], + fromprop: %i[field_97], value: value_fields, equity: equity_fields, mortgage: mortgage_fields, extrabor: extrabor_fields, deposit: deposit_fields, - cashdis: %i[field_92], + cashdis: %i[field_105], mrent: mrent_fields, has_mscharge: mscharge_fields, mscharge: mscharge_fields, - grant: %i[field_114], - discount: %i[field_115], + grant: %i[field_129], + discount: %i[field_130], owning_organisation_id: %i[field_4], managing_organisation_id: [:field_5], assigned_to: %i[field_6], - hhregres: %i[field_65], - hhregresstill: %i[field_66], - armedforcesspouse: %i[field_67], + hhregres: %i[field_78], + hhregresstill: %i[field_79], + armedforcesspouse: %i[field_80], - hb: %i[field_74], + hb: %i[field_87], mortlen: mortlen_fields, mortlen_known: mortlen_fields, proplen: proplen_fields, @@ -830,12 +827,12 @@ private ownershipsch: %i[field_8], jointpur: %i[field_12], - buy1livein: %i[field_33], - buy2livein: %i[field_40], - hholdcount: %i[field_41], - stairbought: %i[field_96], - stairowned: %i[field_97], - socprevten: %i[field_85], + buy1livein: %i[field_36], + buy2livein: %i[field_45], + hholdcount: %i[field_46], + stairbought: %i[field_109], + stairowned: %i[field_110], + socprevten: %i[field_98], mortgageused: mortgageused_fields, uprn: %i[field_16], @@ -845,47 +842,47 @@ private county: %i[field_20], uprn_selection: [:field_17], - ethnic_group2: %i[field_37], - ethnicbuy2: %i[field_37], - nationality_all_buyer2: %i[field_38], - nationality_all_buyer2_group: %i[field_38], - - buy2living: %i[field_63], - prevtenbuy2: %i[field_64], - - prevshared: %i[field_77], - - staircasesale: %i[field_98], - firststair: %i[field_99], - numstair: %i[field_103], - mrentprestaircasing: %i[field_110], - lasttransaction: %i[field_104 field_105 field_106], - initialpurchase: %i[field_100 field_101 field_102], - - sexrab1: %i[field_29], - sexrab2: %i[field_36], - sexrab3: %i[field_44], - sexrab4: %i[field_48], - sexrab5: %i[field_52], - sexrab6: %i[field_56], - - buildheightclass: %i[field_122], - - 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], + ethnic_group2: %i[field_42], + ethnicbuy2: %i[field_42], + nationality_all_buyer2: %i[field_43], + nationality_all_buyer2_group: %i[field_43], + + buy2living: %i[field_76], + prevtenbuy2: %i[field_77], + + prevshared: %i[field_90], + + staircasesale: %i[field_111], + firststair: %i[field_112], + numstair: %i[field_116], + mrentprestaircasing: %i[field_123], + lasttransaction: %i[field_117 field_118 field_119], + initialpurchase: %i[field_113 field_114 field_115], + + sexrab1: %i[field_30], + sexrab2: %i[field_39], + sexrab3: %i[field_49], + sexrab4: %i[field_55], + sexrab5: %i[field_61], + sexrab6: %i[field_67], + + buildheightclass: %i[field_25], + + gender_same_as_sex1: %i[field_31], + gender_description1: %i[field_32], + gender_same_as_sex2: %i[field_40], + gender_description2: %i[field_41], + gender_same_as_sex3: %i[field_50], + gender_description3: %i[field_51], + gender_same_as_sex4: %i[field_56], + gender_description4: %i[field_57], + gender_same_as_sex5: %i[field_62], + gender_description5: %i[field_63], + gender_same_as_sex6: %i[field_68], + gender_description6: %i[field_69], + + hasservicechargeschanged: %i[field_125], + newservicecharges: %i[field_126], } end @@ -897,59 +894,59 @@ private attributes["noint"] = field_14 attributes["age1_known"] = age1_known? - attributes["age1"] = field_28 if attributes["age1_known"]&.zero? && field_28&.match(/\A\d{1,3}\z|\AR\z/) + attributes["age1"] = field_29 if attributes["age1_known"]&.zero? && field_29&.match(/\A\d{1,3}\z|\AR\z/) attributes["age2_known"] = age2_known? - attributes["age2"] = field_35 if attributes["age2_known"]&.zero? && field_35&.match(/\A\d{1,3}\z|\AR\z/) + attributes["age2"] = field_38 if attributes["age2_known"]&.zero? && field_38&.match(/\A\d{1,3}\z|\AR\z/) attributes["age3_known"] = age3_known? - attributes["age3"] = field_43 if attributes["age3_known"]&.zero? && field_43&.match(/\A\d{1,3}\z|\AR\z/) + attributes["age3"] = field_48 if attributes["age3_known"]&.zero? && field_48&.match(/\A\d{1,3}\z|\AR\z/) attributes["age4_known"] = age4_known? - attributes["age4"] = field_47 if attributes["age4_known"]&.zero? && field_47&.match(/\A\d{1,3}\z|\AR\z/) + attributes["age4"] = field_54 if attributes["age4_known"]&.zero? && field_54&.match(/\A\d{1,3}\z|\AR\z/) attributes["age5_known"] = age5_known? - attributes["age5"] = field_51 if attributes["age5_known"]&.zero? && field_51&.match(/\A\d{1,3}\z|\AR\z/) + attributes["age5"] = field_60 if attributes["age5_known"]&.zero? && field_60&.match(/\A\d{1,3}\z|\AR\z/) attributes["age6_known"] = age6_known? - attributes["age6"] = field_55 if attributes["age6_known"]&.zero? && field_55&.match(/\A\d{1,3}\z|\AR\z/) - - attributes["sexrab1"] = field_29 - attributes["sexrab2"] = field_36 - attributes["sexrab3"] = field_44 - attributes["sexrab4"] = field_48 - attributes["sexrab5"] = field_52 - attributes["sexrab6"] = field_56 - attributes["buildheightclass"] = field_122 - - 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) - attributes["relat4"] = relationship_from_is_partner(field_46) - attributes["relat5"] = relationship_from_is_partner(field_50) - attributes["relat6"] = relationship_from_is_partner(field_54) - - attributes["ecstat1"] = field_32 - attributes["ecstat2"] = field_39 - attributes["ecstat3"] = field_45 - attributes["ecstat4"] = field_49 - attributes["ecstat5"] = field_53 - attributes["ecstat6"] = field_57 + attributes["age6"] = field_66 if attributes["age6_known"]&.zero? && field_66&.match(/\A\d{1,3}\z|\AR\z/) + + attributes["sexrab1"] = field_30 + attributes["sexrab2"] = field_39 + attributes["sexrab3"] = field_49 + attributes["sexrab4"] = field_55 + attributes["sexrab5"] = field_61 + attributes["sexrab6"] = field_67 + attributes["buildheightclass"] = field_25 + + attributes["gender_same_as_sex1"] = field_31 + attributes["gender_description1"] = field_32 + attributes["gender_same_as_sex2"] = field_40 + attributes["gender_description2"] = field_41 + attributes["gender_same_as_sex3"] = field_50 + attributes["gender_description3"] = field_51 + attributes["gender_same_as_sex4"] = field_56 + attributes["gender_description4"] = field_57 + attributes["gender_same_as_sex5"] = field_62 + attributes["gender_description5"] = field_63 + attributes["gender_same_as_sex6"] = field_68 + attributes["gender_description6"] = field_69 + + attributes["hasservicechargeschanged"] = field_125 + attributes["newservicecharges"] = field_126 + + attributes["relat2"] = relationship_from_is_partner(field_37) + attributes["relat3"] = relationship_from_is_partner(field_47) + attributes["relat4"] = relationship_from_is_partner(field_53) + attributes["relat5"] = relationship_from_is_partner(field_59) + attributes["relat6"] = relationship_from_is_partner(field_65) + + attributes["ecstat1"] = field_35 + attributes["ecstat2"] = field_44 + attributes["ecstat3"] = field_52 + attributes["ecstat4"] = field_58 + attributes["ecstat5"] = field_64 + attributes["ecstat6"] = field_70 attributes["details_known_2"] = details_known?(2) attributes["details_known_3"] = details_known?(3) @@ -958,34 +955,34 @@ private attributes["details_known_6"] = details_known?(6) attributes["ethnic_group"] = ethnic_group_from_ethnic - attributes["ethnic"] = field_30 - attributes["nationality_all"] = field_31 if field_31.present? && valid_nationality_options.include?(field_31.to_s) + attributes["ethnic"] = field_33 + attributes["nationality_all"] = field_34 if field_34.present? && valid_nationality_options.include?(field_34.to_s) attributes["nationality_all_group"] = nationality_group(attributes["nationality_all"]) - attributes["income1nk"] = field_70 == "R" ? 1 : 0 - attributes["income1"] = field_70.to_i if attributes["income1nk"]&.zero? && field_70&.match(/\A\d+\z/) + attributes["income1nk"] = field_83 == "R" ? 1 : 0 + attributes["income1"] = field_83.to_i if attributes["income1nk"]&.zero? && field_83&.match(/\A\d+\z/) - attributes["income2nk"] = field_72 == "R" ? 1 : 0 - attributes["income2"] = field_72.to_i if attributes["income2nk"]&.zero? && field_72&.match(/\A\d+\z/) + attributes["income2nk"] = field_85 == "R" ? 1 : 0 + attributes["income2"] = field_85.to_i if attributes["income2nk"]&.zero? && field_85&.match(/\A\d+\z/) - attributes["inc1mort"] = field_71 - attributes["inc2mort"] = field_73 + attributes["inc1mort"] = field_84 + attributes["inc2mort"] = field_86 - attributes["savingsnk"] = field_75 == "R" ? 1 : 0 - attributes["savings"] = field_75.to_i if attributes["savingsnk"]&.zero? && field_75&.match(/\A\d+\z/) - attributes["prevown"] = field_76 + attributes["savingsnk"] = field_88 == "R" ? 1 : 0 + attributes["savings"] = field_88.to_i if attributes["savingsnk"]&.zero? && field_88&.match(/\A\d+\z/) + attributes["prevown"] = field_89 - attributes["prevten"] = field_58 - attributes["prevloc"] = field_62 + attributes["prevten"] = field_71 + attributes["prevloc"] = field_75 attributes["previous_la_known"] = previous_la_known attributes["ppcodenk"] = previous_postcode_known attributes["ppostcode_full"] = ppostcode_full - attributes["disabled"] = field_68 - attributes["wheel"] = field_69 - attributes["beds"] = field_25 + attributes["disabled"] = field_81 + attributes["wheel"] = field_82 + attributes["beds"] = field_26 attributes["proptype"] = field_24 - attributes["builtype"] = field_26 + attributes["builtype"] = field_27 attributes["la_known"] = field_23.present? ? 1 : 0 attributes["la"] = field_23 attributes["la_as_entered"] = field_23 @@ -993,15 +990,15 @@ private attributes["pcodenk"] = 0 if postcode_full.present? attributes["postcode_full"] = postcode_full attributes["postcode_full_as_entered"] = postcode_full - attributes["wchair"] = field_27 + attributes["wchair"] = field_28 attributes["type"] = sale_type - attributes["resale"] = field_78 + attributes["resale"] = field_91 attributes["hodate"] = hodate - attributes["frombeds"] = field_83 - attributes["fromprop"] = field_84 + attributes["frombeds"] = field_96 + attributes["fromprop"] = field_97 attributes["value"] = value attributes["equity"] = equity @@ -1009,22 +1006,22 @@ private attributes["extrabor"] = extrabor attributes["deposit"] = deposit - attributes["cashdis"] = field_92 + attributes["cashdis"] = field_105 attributes["mrent"] = mrent attributes["mscharge"] = mscharge if mscharge&.positive? attributes["has_mscharge"] = attributes["mscharge"].present? ? 1 : 0 - attributes["grant"] = field_114 - attributes["discount"] = field_115 + attributes["grant"] = field_129 + attributes["discount"] = field_130 attributes["owning_organisation"] = owning_organisation attributes["managing_organisation"] = managing_organisation attributes["assigned_to"] = assigned_to || (bulk_upload.user.support? ? nil : bulk_upload.user) attributes["created_by"] = bulk_upload.user - attributes["hhregres"] = field_65 - attributes["hhregresstill"] = field_66 - attributes["armedforcesspouse"] = field_67 + attributes["hhregres"] = field_78 + attributes["hhregresstill"] = field_79 + attributes["armedforcesspouse"] = field_80 - attributes["hb"] = field_74 + attributes["hb"] = field_87 attributes["mortlen"] = mortlen != "R" ? mortlen : nil attributes["mortlen_known"] = mortlen_known @@ -1036,12 +1033,12 @@ private attributes["privacynotice"] = field_15 attributes["ownershipsch"] = field_8 attributes["jointpur"] = field_12 - attributes["buy1livein"] = field_33 - attributes["buy2livein"] = field_40 - attributes["hholdcount"] = field_41 - attributes["stairbought"] = field_96 - attributes["stairowned"] = field_97 - attributes["socprevten"] = field_85 + attributes["buy1livein"] = field_36 + attributes["buy2livein"] = field_45 + attributes["hholdcount"] = field_46 + attributes["stairbought"] = field_109 + attributes["stairowned"] = field_110 + attributes["socprevten"] = field_98 attributes["soctenant"] = infer_soctenant_from_prevten_and_prevtenbuy2 attributes["mortgageused"] = mortgageused @@ -1062,25 +1059,25 @@ private attributes["select_best_address_match"] = true if field_16.blank? attributes["ethnic_group2"] = infer_buyer2_ethnic_group_from_ethnic - attributes["ethnicbuy2"] = field_37 - attributes["nationality_all_buyer2"] = field_38 if field_38.present? && valid_nationality_options.include?(field_38.to_s) + attributes["ethnicbuy2"] = field_42 + attributes["nationality_all_buyer2"] = field_43 if field_43.present? && valid_nationality_options.include?(field_43.to_s) attributes["nationality_all_buyer2_group"] = nationality_group(attributes["nationality_all_buyer2"]) - attributes["buy2living"] = field_63 + attributes["buy2living"] = field_76 attributes["prevtenbuy2"] = prevtenbuy2 - attributes["prevshared"] = field_77 + attributes["prevshared"] = field_90 - attributes["staircasesale"] = field_98 + attributes["staircasesale"] = field_111 - attributes["firststair"] = field_99 - attributes["numstair"] = field_103 - attributes["mrentprestaircasing"] = field_110 + attributes["firststair"] = field_112 + attributes["numstair"] = field_116 + attributes["mrentprestaircasing"] = field_123 attributes["lasttransaction"] = lasttransaction attributes["initialpurchase"] = initialpurchase - attributes["management_fee"] = field_95 - attributes["has_management_fee"] = field_95.present? && field_95.positive? ? 1 : 0 + attributes["management_fee"] = field_108 + attributes["has_management_fee"] = field_108.present? && field_108.positive? ? 1 : 0 attributes end @@ -1097,38 +1094,38 @@ private end def hodate - year = field_82.to_s.strip.length.between?(1, 2) ? field_82 + 2000 : field_82 - Date.new(year, field_81, field_80) if field_82.present? && field_81.present? && field_80.present? + year = field_95.to_s.strip.length.between?(1, 2) ? field_95 + 2000 : field_95 + Date.new(year, field_94, field_93) if field_95.present? && field_94.present? && field_93.present? rescue Date::Error Date.new end def lasttransaction - year = field_106.to_s.strip.length.between?(1, 2) ? field_106 + 2000 : field_106 - Date.new(year, field_105, field_104) if field_106.present? && field_105.present? && field_104.present? + year = field_119.to_s.strip.length.between?(1, 2) ? field_119 + 2000 : field_119 + Date.new(year, field_118, field_117) if field_119.present? && field_118.present? && field_117.present? rescue Date::Error Date.new end def initialpurchase - year = field_102.to_s.strip.length.between?(1, 2) ? field_102 + 2000 : field_102 - Date.new(year, field_101, field_100) if field_102.present? && field_101.present? && field_100.present? + year = field_115.to_s.strip.length.between?(1, 2) ? field_115 + 2000 : field_115 + Date.new(year, field_114, field_113) if field_115.present? && field_114.present? && field_113.present? rescue Date::Error Date.new end def age1_known? - return 1 if field_28 == "R" + return 1 if field_29 == "R" 0 end [ - { person: 2, field: :field_35 }, - { person: 3, field: :field_43 }, - { person: 4, field: :field_47 }, - { person: 5, field: :field_51 }, - { person: 6, field: :field_55 }, + { person: 2, field: :field_38 }, + { person: 3, field: :field_48 }, + { person: 4, field: :field_54 }, + { person: 5, field: :field_60 }, + { person: 6, field: :field_66 }, ].each do |hash| define_method("age#{hash[:person]}_known?") do return 1 if public_send(hash[:field]) == "R" @@ -1138,23 +1135,23 @@ private end def person_2_present? - field_35.present? || field_36.present? || field_34.present? || field_125.present? || field_126.present? + field_38.present? || field_39.present? || field_37.present? || field_40.present? || field_41.present? end def person_3_present? - field_43.present? || field_44.present? || field_42.present? || field_127.present? || field_128.present? + field_48.present? || field_49.present? || field_47.present? || field_50.present? || field_51.present? end def person_4_present? - field_47.present? || field_48.present? || field_46.present? || field_129.present? || field_130.present? + field_54.present? || field_55.present? || field_53.present? || field_56.present? || field_57.present? end def person_5_present? - field_51.present? || field_52.present? || field_50.present? || field_131.present? || field_132.present? + field_60.present? || field_61.present? || field_59.present? || field_62.present? || field_63.present? end def person_6_present? - field_55.present? || field_56.present? || field_54.present? || field_133.present? || field_134.present? + field_66.present? || field_67.present? || field_65.present? || field_68.present? || field_69.present? end def relationship_from_is_partner(is_partner) @@ -1173,9 +1170,9 @@ private end def ethnic_group_from_ethnic - return nil if field_30.blank? + return nil if field_33.blank? - case field_30 + case field_33 when 1, 2, 3, 18, 20 0 when 4, 5, 6, 7 @@ -1196,7 +1193,7 @@ private end def ppostcode_full - "#{field_60} #{field_61}" if field_60 && field_61 + "#{field_73} #{field_74}" if field_73 && field_74 end def sale_type @@ -1206,50 +1203,50 @@ private end def value - return field_86 if shared_ownership_initial_purchase? - return field_113 if discounted_ownership? + return field_99 if shared_ownership_initial_purchase? + return field_128 if discounted_ownership? - field_107 if staircasing? + field_120 if staircasing? end def equity - return field_87 if shared_ownership_initial_purchase? + return field_100 if shared_ownership_initial_purchase? - field_108 if staircasing? + field_121 if staircasing? end def mortgage - return field_89 if shared_ownership? + return field_102 if shared_ownership? - field_117 if discounted_ownership? + field_132 if discounted_ownership? end def extrabor - field_119 if discounted_ownership? + field_134 if discounted_ownership? end def deposit - return field_91 if shared_ownership? + return field_104 if shared_ownership? - field_120 if discounted_ownership? + field_135 if discounted_ownership? end def mrent - return field_93 if shared_ownership_initial_purchase? + return field_106 if shared_ownership_initial_purchase? - field_111 if staircasing? + field_124 if staircasing? end def mscharge - return field_94 if shared_ownership? + return field_107 if shared_ownership? - field_121 if discounted_ownership? + field_136 if discounted_ownership? end def mortlen - return field_90 if shared_ownership? + return field_103 if shared_ownership? - field_118 if discounted_ownership? + field_133 if discounted_ownership? end def mortlen_known @@ -1263,87 +1260,87 @@ private end def proplen - return field_79 if shared_ownership? + return field_92 if shared_ownership? - field_112 if discounted_ownership? + field_127 if discounted_ownership? end def mortgageused - return field_88 if shared_ownership_initial_purchase? - return field_116 if discounted_ownership? + return field_101 if shared_ownership_initial_purchase? + return field_131 if discounted_ownership? - field_109 if staircasing? + field_122 if staircasing? end def value_fields - return [:field_86] if shared_ownership_initial_purchase? - return [:field_113] if discounted_ownership? - return [:field_107] if staircasing? + return [:field_99] if shared_ownership_initial_purchase? + return [:field_128] if discounted_ownership? + return [:field_120] if staircasing? - %i[field_86 field_113 field_107] + %i[field_99 field_128 field_120] end def equity_fields - return [:field_87] if shared_ownership_initial_purchase? - return [:field_108] if staircasing? + return [:field_100] if shared_ownership_initial_purchase? + return [:field_121] if staircasing? - %i[field_87 field_108] + %i[field_100 field_121] end def mortgage_fields - return [:field_89] if shared_ownership? - return [:field_117] if discounted_ownership? + return [:field_102] if shared_ownership? + return [:field_132] if discounted_ownership? - %i[field_89 field_117] + %i[field_102 field_132] end def extrabor_fields - return [:field_119] if discounted_ownership? + return [:field_134] if discounted_ownership? - %i[field_119] + %i[field_134] end def deposit_fields - return [:field_91] if shared_ownership? - return [:field_120] if discounted_ownership? + return [:field_104] if shared_ownership? + return [:field_135] if discounted_ownership? - %i[field_91 field_120] + %i[field_104 field_135] end def mrent_fields - return [:field_93] if shared_ownership_initial_purchase? - return [:field_111] if staircasing? + return [:field_106] if shared_ownership_initial_purchase? + return [:field_124] if staircasing? - %i[field_93 field_111] + %i[field_106 field_124] end def mscharge_fields - return [:field_94] if shared_ownership? - return [:field_121] if discounted_ownership? + return [:field_107] if shared_ownership? + return [:field_136] if discounted_ownership? - %i[field_94 field_121] + %i[field_107 field_136] end def mortlen_fields - return [:field_90] if shared_ownership? - return [:field_118] if discounted_ownership? + return [:field_103] if shared_ownership? + return [:field_133] if discounted_ownership? - %i[field_90 field_118] + %i[field_103 field_133] end def proplen_fields - return [:field_79] if shared_ownership? - return [:field_112] if discounted_ownership? + return [:field_92] if shared_ownership? + return [:field_127] if discounted_ownership? - %i[field_79 field_112] + %i[field_92 field_127] end def mortgageused_fields - return [:field_88] if shared_ownership_initial_purchase? - return [:field_116] if discounted_ownership? - return [:field_109] if staircasing? + return [:field_101] if shared_ownership_initial_purchase? + return [:field_131] if discounted_ownership? + return [:field_122] if staircasing? - %i[field_88 field_116 field_109] + %i[field_101 field_131 field_122] end def owning_organisation @@ -1355,19 +1352,19 @@ private end def previous_la_known - field_62.present? ? 1 : 0 + field_75.present? ? 1 : 0 end def previous_postcode_known - return 1 if field_59 == 2 + return 1 if field_72 == 2 - 0 if field_59 == 1 + 0 if field_72 == 1 end def infer_soctenant_from_prevten_and_prevtenbuy2 return unless shared_ownership? - if [1, 2].include?(field_58) || [1, 2].include?(field_64.to_i) + if [1, 2].include?(field_71) || [1, 2].include?(field_77.to_i) 1 else 2 @@ -1562,9 +1559,9 @@ private errors.add(:field_3, error_message) # Sale completion date errors.add(:field_21, error_message) # Postcode errors.add(:field_22, error_message) # Postcode - errors.add(:field_28, error_message) # Buyer 1 age - errors.add(:field_29, error_message) # Buyer 1 sex registered at birth - errors.add(:field_32, error_message) # Buyer 1 working situation + errors.add(:field_29, error_message) # Buyer 1 age + errors.add(:field_30, error_message) # Buyer 1 sex registered at birth + errors.add(:field_35, error_message) # Buyer 1 working situation errors.add(:field_7, error_message) # Purchaser code end end @@ -1588,12 +1585,12 @@ private end def validate_buyer1_economic_status - if field_32 == 9 - if field_28.present? && field_28.to_i >= 16 - errors.add(:field_32, I18n.t("#{ERROR_BASE_KEY}.ecstat1.buyer_cannot_be_over_16_and_child")) - errors.add(:field_28, I18n.t("#{ERROR_BASE_KEY}.age1.buyer_cannot_be_over_16_and_child")) + if field_35 == 9 + if field_29.present? && field_29.to_i >= 16 + errors.add(:field_35, I18n.t("#{ERROR_BASE_KEY}.ecstat1.buyer_cannot_be_over_16_and_child")) + errors.add(:field_29, I18n.t("#{ERROR_BASE_KEY}.age1.buyer_cannot_be_over_16_and_child")) else - errors.add(:field_32, I18n.t("#{ERROR_BASE_KEY}.ecstat1.buyer_cannot_be_child")) + errors.add(:field_35, I18n.t("#{ERROR_BASE_KEY}.ecstat1.buyer_cannot_be_child")) end end end @@ -1601,25 +1598,25 @@ private def validate_buyer2_economic_status return unless joint_purchase? - if field_39 == 9 - if field_35.present? && field_35.to_i >= 16 - errors.add(:field_39, I18n.t("#{ERROR_BASE_KEY}.ecstat2.buyer_cannot_be_over_16_and_child")) - errors.add(:field_35, I18n.t("#{ERROR_BASE_KEY}.age2.buyer_cannot_be_over_16_and_child")) + if field_44 == 9 + if field_38.present? && field_38.to_i >= 16 + errors.add(:field_44, I18n.t("#{ERROR_BASE_KEY}.ecstat2.buyer_cannot_be_over_16_and_child")) + errors.add(:field_38, I18n.t("#{ERROR_BASE_KEY}.age2.buyer_cannot_be_over_16_and_child")) else - errors.add(:field_39, I18n.t("#{ERROR_BASE_KEY}.ecstat2.buyer_cannot_be_child")) + errors.add(:field_44, I18n.t("#{ERROR_BASE_KEY}.ecstat2.buyer_cannot_be_child")) end end end def validate_nationality - if field_31.present? && !valid_nationality_options.include?(field_31.to_s) - errors.add(:field_31, I18n.t("#{ERROR_BASE_KEY}.nationality.invalid")) + if field_34.present? && !valid_nationality_options.include?(field_34.to_s) + errors.add(:field_34, I18n.t("#{ERROR_BASE_KEY}.nationality.invalid")) end end def validate_buyer_2_nationality - if field_38.present? && !valid_nationality_options.include?(field_38.to_s) - errors.add(:field_38, I18n.t("#{ERROR_BASE_KEY}.nationality.invalid")) + if field_43.present? && !valid_nationality_options.include?(field_43.to_s) + errors.add(:field_43, I18n.t("#{ERROR_BASE_KEY}.nationality.invalid")) end end @@ -1629,8 +1626,8 @@ private def validate_mortlen_field_if_buyer_interviewed if buyer_interviewed? && mortlen == "R" - errors.add(:field_90, I18n.t("#{ERROR_BASE_KEY}.mortlen.invalid_for_interviewed")) if shared_ownership? - errors.add(:field_118, I18n.t("#{ERROR_BASE_KEY}.mortlen.invalid_for_interviewed")) if discounted_ownership? + errors.add(:field_103, I18n.t("#{ERROR_BASE_KEY}.mortlen.invalid_for_interviewed")) if shared_ownership? + errors.add(:field_133, I18n.t("#{ERROR_BASE_KEY}.mortlen.invalid_for_interviewed")) if discounted_ownership? end end diff --git a/spec/services/bulk_upload/sales/year2026/csv_parser_spec.rb b/spec/services/bulk_upload/sales/year2026/csv_parser_spec.rb index 09e135400..c5b253106 100644 --- a/spec/services/bulk_upload/sales/year2026/csv_parser_spec.rb +++ b/spec/services/bulk_upload/sales/year2026/csv_parser_spec.rb @@ -166,7 +166,7 @@ RSpec.describe BulkUpload::Sales::Year2026::CsvParser do it "returns correct column" do expect(service.column_for_field("field_1")).to eql("B") - expect(service.column_for_field("field_99")).to eql("CV") + expect(service.column_for_field("field_126")).to eql("DW") end end end diff --git a/spec/services/bulk_upload/sales/year2026/row_parser_spec.rb b/spec/services/bulk_upload/sales/year2026/row_parser_spec.rb index 092e86b58..e2b134f0e 100644 --- a/spec/services/bulk_upload/sales/year2026/row_parser_spec.rb +++ b/spec/services/bulk_upload/sales/year2026/row_parser_spec.rb @@ -51,73 +51,73 @@ RSpec.describe BulkUpload::Sales::Year2026::RowParser do field_22: "4BB", field_23: "E09000008", field_24: "1", - field_25: "2", - field_26: "1", - field_27: "3", - field_28: "32", - field_29: "M", - field_30: "12", - field_31: "28", - field_32: "1", - field_33: "1", - field_34: "3", - field_35: "32", - field_36: "F", - field_37: "17", - field_38: "28", - field_39: "2", - field_40: "1", - field_41: "0", - field_58: "1", - field_59: "1", - field_60: "A1", - field_61: "1AA", - field_62: "E09000008", - field_63: "3", - field_65: "3", - field_67: "5", - field_68: "3", - field_69: "3", - field_70: "30000", + field_26: "2", + field_27: "1", + field_28: "3", + field_29: "32", + field_30: "M", + field_33: "12", + field_34: "28", + field_35: "1", + field_36: "1", + field_37: "3", + field_38: "32", + field_39: "F", + field_42: "17", + field_43: "28", + field_44: "2", + field_45: "1", + field_46: "0", field_71: "1", - field_72: "15000", - field_73: "1", - field_74: "4", - field_75: "20000", + field_72: "1", + field_73: "A1", + field_74: "1AA", + field_75: "E09000008", field_76: "3", - field_79: "5", - field_80: "24", + field_78: "3", + field_80: "5", field_81: "3", - field_82: "2022", - field_83: "1", + field_82: "3", + field_83: "30000", field_84: "1", - field_85: "1", - field_107: "250000", - field_108: "25", - field_109: "1", - field_89: "5000", - field_90: "20", - field_96: "10", - field_97: "40", + field_85: "15000", + field_86: "1", + field_87: "4", + field_88: "20000", + field_89: "3", + field_92: "5", + field_93: "24", + field_94: "3", + field_95: "2022", + field_96: "1", + field_97: "1", field_98: "1", - field_99: "2", - field_94: "200", - field_91: "20000", - field_111: "800", - field_100: "05", - field_101: "04", - field_102: "2020", - field_103: "4", - field_104: "06", - field_105: "07", - field_106: "2023", - field_110: "900", + field_120: "250000", + field_121: "25", field_122: "1", - field_123: "1", - field_125: "2", - field_126: "Non-binary", - field_135: "1", - field_136: "150", + field_102: "5000", + field_103: "20", + field_109: "10", + field_110: "40", + field_111: "1", + field_112: "2", + field_107: "200", + field_104: "20000", + field_124: "800", + field_113: "05", + field_114: "04", + field_115: "2020", + field_116: "4", + field_117: "06", + field_118: "07", + field_119: "2023", + field_123: "900", + field_25: "1", + field_31: "1", + field_40: "2", + field_41: "Non-binary", + field_125: "1", + field_126: "150", } end @@ -150,7 +150,7 @@ RSpec.describe BulkUpload::Sales::Year2026::RowParser do context "when the only populated fields are empty strings or whitespace" do before do parser.field_6 = " " - parser.field_25 = "" + parser.field_26 = "" end it "returns true" do @@ -179,11 +179,11 @@ RSpec.describe BulkUpload::Sales::Year2026::RowParser do end describe "previous postcode known" do - context "when field_59 is 1" do + context "when field_72 is 1" do let(:attributes) do { bulk_upload:, - field_59: 1, + field_72: 1, } end @@ -192,11 +192,11 @@ RSpec.describe BulkUpload::Sales::Year2026::RowParser do end end - context "when field_59 is 2" do + context "when field_72 is 2" do let(:attributes) do { bulk_upload:, - field_59: 2, + field_72: 2, } end @@ -211,9 +211,9 @@ RSpec.describe BulkUpload::Sales::Year2026::RowParser do let(:attributes) do { bulk_upload:, - field_70: "R", # income 1 - field_72: "R", # income 2 - field_75: "R", # savings + field_83: "R", # income 1 + field_85: "R", # income 2 + field_88: "R", # savings } end @@ -234,9 +234,9 @@ RSpec.describe BulkUpload::Sales::Year2026::RowParser do let(:attributes) do { bulk_upload:, - field_70: "30000", # income 1 - field_72: "0", # income 2 - field_75: "12420", # savings + field_83: "30000", # income 1 + field_85: "0", # income 2 + field_88: "12420", # savings } end @@ -300,8 +300,8 @@ RSpec.describe BulkUpload::Sales::Year2026::RowParser do end context "and case insensitive fields are set to lowercase" do - let(:case_insensitive_fields) { %w[field_29 field_36 field_44 field_48 field_52 field_56] } - let(:case_insensitive_integer_fields_with_r_option) { %w[field_28 field_35 field_43 field_47 field_51 field_55 field_64 field_75 field_70 field_72 field_90 field_118] } + let(:case_insensitive_fields) { %w[field_30 field_39 field_49 field_55 field_61 field_67] } + let(:case_insensitive_integer_fields_with_r_option) { %w[field_29 field_38 field_48 field_54 field_60 field_66 field_77 field_88 field_83 field_85 field_103 field_133] } let(:attributes) do valid_attributes .merge(case_insensitive_fields.each_with_object({}) { |field, h| h[field.to_sym] = valid_attributes[field.to_sym]&.downcase }) @@ -316,11 +316,11 @@ RSpec.describe BulkUpload::Sales::Year2026::RowParser do describe "#validate_nulls" do context "when non-setup questions are null" do - let(:attributes) { setup_section_params.merge({ field_29: "" }) } + let(:attributes) { setup_section_params.merge({ field_30: "" }) } it "fetches the question's check_answer_label if it exists" do parser.valid? - expect(parser.errors[:field_29]).to eql([I18n.t("validations.not_answered", question: "buyer 1’s sex registered at birth.")]) + expect(parser.errors[:field_30]).to eql([I18n.t("validations.not_answered", question: "buyer 1’s sex registered at birth.")]) end end @@ -334,12 +334,12 @@ RSpec.describe BulkUpload::Sales::Year2026::RowParser do end context "when an invalid value error has been added" do - let(:attributes) { setup_section_params.merge({ field_10: "2", field_32: "100" }) } + let(:attributes) { setup_section_params.merge({ field_10: "2", field_35: "100" }) } it "does not add an additional error" do parser.valid? - expect(parser.errors[:field_32].length).to eq(1) - expect(parser.errors[:field_32]).to include(match I18n.t("validations.sales.2026.bulk_upload.invalid_option", question: "")) + expect(parser.errors[:field_35].length).to eq(1) + expect(parser.errors[:field_35]).to include(match I18n.t("validations.sales.2026.bulk_upload.invalid_option", question: "")) end end end @@ -423,9 +423,9 @@ RSpec.describe BulkUpload::Sales::Year2026::RowParser do let(:attributes) do { bulk_upload:, - field_28: "2", - field_43: "8", - field_36: "1", + field_29: "2", + field_48: "8", + field_39: "1", } end @@ -792,9 +792,9 @@ RSpec.describe BulkUpload::Sales::Year2026::RowParser do :field_3, # Sale completion date :field_21, # Postcode :field_22, # Postcode - :field_28, # Buyer 1 age - :field_29, # Buyer 1 sex registered at birth - :field_32, # Buyer 1 working situation + :field_29, # Buyer 1 age + :field_30, # Buyer 1 sex registered at birth + :field_35, # Buyer 1 working situation :field_7, # Purchaser code ].each do |field| expect(parser.errors[field]).to include(error_message) @@ -822,9 +822,9 @@ RSpec.describe BulkUpload::Sales::Year2026::RowParser do :field_3, # Sale completion date :field_21, # Postcode :field_22, # Postcode - :field_28, # Buyer 1 age - :field_29, # Buyer 1 sex registered at birth - :field_32, # Buyer 1 working situation + :field_29, # Buyer 1 age + :field_30, # Buyer 1 sex registered at birth + :field_35, # Buyer 1 working situation :field_7, # Purchaser code ].each do |field| expect(parser.errors[field]).to be_blank @@ -865,31 +865,31 @@ RSpec.describe BulkUpload::Sales::Year2026::RowParser do end end - describe "#field_115" do # percentage discount + describe "#field_130" do # percentage discount context "when percentage discount over 70" do - let(:attributes) { valid_attributes.merge({ field_8: "2", field_10: "2", field_11: "9", field_115: "71" }) } + let(:attributes) { valid_attributes.merge({ field_8: "2", field_10: "2", field_11: "9", field_130: "71" }) } it "returns correct error" do parser.valid? - expect(parser.errors.where(:field_115).map(&:message)).to include(I18n.t("validations.sales.2026.bulk_upload.numeric.within_range", field: "Percentage discount", min: "0%", max: "70%")) + expect(parser.errors.where(:field_130).map(&:message)).to include(I18n.t("validations.sales.2026.bulk_upload.numeric.within_range", field: "Percentage discount", min: "0%", max: "70%")) end end context "when percentage discount not over 70" do - let(:attributes) { valid_attributes.merge({ field_8: "2", field_10: "2", field_115: "70" }) } + let(:attributes) { valid_attributes.merge({ field_8: "2", field_10: "2", field_130: "70" }) } it "does not return error" do parser.valid? - expect(parser.errors.where(:field_115)).not_to be_present + expect(parser.errors.where(:field_130)).not_to be_present end end context "when percentage less than 0" do - let(:attributes) { valid_attributes.merge({ field_8: "2", field_10: "2", field_115: "-1" }) } + let(:attributes) { valid_attributes.merge({ field_8: "2", field_10: "2", field_130: "-1" }) } it "returns correct error" do parser.valid? - expect(parser.errors.where(:field_115).map(&:message)).to include(I18n.t("validations.sales.2026.bulk_upload.numeric.within_range", field: "Percentage discount", min: "0%", max: "70%")) + expect(parser.errors.where(:field_130).map(&:message)).to include(I18n.t("validations.sales.2026.bulk_upload.numeric.within_range", field: "Percentage discount", min: "0%", max: "70%")) end end end @@ -1088,17 +1088,17 @@ RSpec.describe BulkUpload::Sales::Year2026::RowParser do end [ - %w[age1_known details_known_1 age1 field_28 field_34 field_36], - %w[age2_known details_known_2 age2 field_35 field_34 field_36], - %w[age3_known details_known_3 age3 field_43 field_42 field_44], - %w[age4_known details_known_4 age4 field_47 field_46 field_48], - %w[age5_known details_known_5 age5 field_51 field_50 field_52], - %w[age6_known details_known_6 age6 field_55 field_54 field_56], + %w[age1_known details_known_1 age1 field_29 field_37 field_39], + %w[age2_known details_known_2 age2 field_38 field_37 field_39], + %w[age3_known details_known_3 age3 field_48 field_47 field_49], + %w[age4_known details_known_4 age4 field_54 field_53 field_55], + %w[age5_known details_known_5 age5 field_60 field_59 field_61], + %w[age6_known details_known_6 age6 field_66 field_65 field_67], ].each do |known, details_known, age, field, relationship, gender| describe "##{known} and ##{age}" do context "when #{field} is blank" do context "and person details are blank" do - let(:attributes) { setup_section_params.merge({ field.to_s => nil, relationship.to_sym => nil, gender.to_sym => nil, field_15: "1", field_41: "5" }) } + let(:attributes) { setup_section_params.merge({ field.to_s => nil, relationship.to_sym => nil, gender.to_sym => nil, field_15: "1", field_46: "5" }) } it "does not set ##{known}" do unless known == "age1_known" @@ -1118,7 +1118,7 @@ RSpec.describe BulkUpload::Sales::Year2026::RowParser do end context "and person details are given" do - let(:attributes) { setup_section_params.merge({ field.to_sym => nil, relationship.to_sym => "C", gender.to_sym => "X", field_15: "1", field_41: "5" }) } + let(:attributes) { setup_section_params.merge({ field.to_sym => nil, relationship.to_sym => "C", gender.to_sym => "X", field_15: "1", field_46: "5" }) } it "does not set ##{age}" do parser.valid? @@ -1128,7 +1128,7 @@ RSpec.describe BulkUpload::Sales::Year2026::RowParser do end context "when #{field} is R" do - let(:attributes) { setup_section_params.merge({ field.to_s => "R", field_14: "1", field_41: "5", field_15: "1" }) } + let(:attributes) { setup_section_params.merge({ field.to_s => "R", field_14: "1", field_46: "5", field_15: "1" }) } it "sets ##{known} 1" do expect(parser.log.public_send(known)).to be(1) @@ -1140,7 +1140,7 @@ RSpec.describe BulkUpload::Sales::Year2026::RowParser do end context "when #{field} is a number" do - let(:attributes) { setup_section_params.merge({ field.to_s => "50", field_14: "1", field_41: "5", field_15: "1" }) } + let(:attributes) { setup_section_params.merge({ field.to_s => "50", field_14: "1", field_46: "5", field_15: "1" }) } it "sets ##{known} to 0" do expect(parser.log.public_send(known)).to be(0) @@ -1152,7 +1152,7 @@ RSpec.describe BulkUpload::Sales::Year2026::RowParser do end context "when #{field} is a non-sensical value" do - let(:attributes) { setup_section_params.merge({ field.to_s => "A", field_14: "1", field_41: "5", field_15: "1" }) } + let(:attributes) { setup_section_params.merge({ field.to_s => "A", field_14: "1", field_46: "5", field_15: "1" }) } it "sets ##{known} to 0" do expect(parser.log.public_send(known)).to be(0) @@ -1167,15 +1167,15 @@ RSpec.describe BulkUpload::Sales::Year2026::RowParser do describe "relationship field mappings" do [ - %w[field_34 relat2 2], - %w[field_42 relat3 3], - %w[field_46 relat4 4], - %w[field_50 relat5 5], - %w[field_54 relat6 6], + %w[field_37 relat2 2], + %w[field_47 relat3 3], + %w[field_53 relat4 4], + %w[field_59 relat5 5], + %w[field_65 relat6 6], ].each do |input_field, relationship_attribute, person_num| describe input_field.to_s do context "when #{input_field} is 1" do - let(:attributes) { setup_section_params.merge({ input_field.to_sym => "1", field_41: "5" }) } + let(:attributes) { setup_section_params.merge({ input_field.to_sym => "1", field_46: "5" }) } it "sets relationship to P" do expect(parser.log.public_send(relationship_attribute)).to eq("P") @@ -1183,7 +1183,7 @@ RSpec.describe BulkUpload::Sales::Year2026::RowParser do end context "when #{input_field} is 2" do - let(:attributes) { setup_section_params.merge({ input_field.to_sym => "2", field_41: "5" }) } + let(:attributes) { setup_section_params.merge({ input_field.to_sym => "2", field_46: "5" }) } it "sets relationship to X" do expect(parser.log.public_send(relationship_attribute)).to eq("X") @@ -1191,7 +1191,7 @@ RSpec.describe BulkUpload::Sales::Year2026::RowParser do end context "when #{input_field} is 3" do - let(:attributes) { setup_section_params.merge({ input_field.to_sym => "3", field_41: "5" }) } + let(:attributes) { setup_section_params.merge({ input_field.to_sym => "3", field_46: "5" }) } it "sets relationship to R" do expect(parser.log.public_send(relationship_attribute)).to eq("R") @@ -1199,7 +1199,7 @@ RSpec.describe BulkUpload::Sales::Year2026::RowParser do end context "when #{input_field} is 4" do - let(:attributes) { setup_section_params.merge({ input_field.to_sym => "4", field_41: "5" }) } + let(:attributes) { setup_section_params.merge({ input_field.to_sym => "4", field_46: "5" }) } it "gives a validation error" do parser.valid? @@ -1211,102 +1211,102 @@ RSpec.describe BulkUpload::Sales::Year2026::RowParser do end end - describe "field_39" do # ecstat2 + describe "field_44" do # ecstat2 context "when buyer 2 has no age but has ecstat as child" do - let(:attributes) { valid_attributes.merge({ field_35: nil, field_39: "9" }) } + let(:attributes) { valid_attributes.merge({ field_38: nil, field_44: "9" }) } it "a custom validation is applied" do parser.valid? - expect(parser.errors[:field_39]).to include I18n.t("validations.sales.2026.bulk_upload.ecstat2.buyer_cannot_be_child") + expect(parser.errors[:field_44]).to include I18n.t("validations.sales.2026.bulk_upload.ecstat2.buyer_cannot_be_child") end end context "when buyer 2 is under 16" do - let(:attributes) { valid_attributes.merge({ field_35: "9" }) } + let(:attributes) { valid_attributes.merge({ field_38: "9" }) } it "a custom validation is applied" do parser.valid? validation_message = "Buyer 2’s age must be between 16 and 110." - expect(parser.errors[:field_35]).to include validation_message + expect(parser.errors[:field_38]).to include validation_message end end context "when buyer 2 is over 16 but has ecstat as child" do - let(:attributes) { valid_attributes.merge({ field_35: "17", field_39: "9" }) } + let(:attributes) { valid_attributes.merge({ field_38: "17", field_44: "9" }) } it "a custom validation is applied" do parser.valid? - expect(parser.errors[:field_39]).to include I18n.t("validations.sales.2026.bulk_upload.ecstat2.buyer_cannot_be_over_16_and_child") - expect(parser.errors[:field_35]).to include I18n.t("validations.sales.2026.bulk_upload.age2.buyer_cannot_be_over_16_and_child") + expect(parser.errors[:field_44]).to include I18n.t("validations.sales.2026.bulk_upload.ecstat2.buyer_cannot_be_over_16_and_child") + expect(parser.errors[:field_38]).to include I18n.t("validations.sales.2026.bulk_upload.age2.buyer_cannot_be_over_16_and_child") end end context "when person 2 a child but not a buyer" do - let(:attributes) { valid_attributes.merge({ field_12: 2, field_35: "10", field_39: "9" }) } + let(:attributes) { valid_attributes.merge({ field_12: 2, field_38: "10", field_44: "9" }) } it "does not add errors to their age and ecstat fields" do parser.valid? - expect(parser.errors[:field_35]).to be_empty - expect(parser.errors[:field_39]).to be_empty + expect(parser.errors[:field_38]).to be_empty + expect(parser.errors[:field_44]).to be_empty end end end - describe "field_32" do # ecstat1 + describe "field_35" do # ecstat1 context "when buyer 1 has no age but has ecstat as child" do - let(:attributes) { valid_attributes.merge({ field_28: nil, field_32: "9" }) } + let(:attributes) { valid_attributes.merge({ field_29: nil, field_35: "9" }) } it "a custom validation is applied" do parser.valid? - expect(parser.errors[:field_32]).to include I18n.t("validations.sales.2026.bulk_upload.ecstat1.buyer_cannot_be_child") + expect(parser.errors[:field_35]).to include I18n.t("validations.sales.2026.bulk_upload.ecstat1.buyer_cannot_be_child") end end context "when buyer 1 is under 16" do - let(:attributes) { valid_attributes.merge({ field_28: "9" }) } + let(:attributes) { valid_attributes.merge({ field_29: "9" }) } it "a custom validation is applied" do parser.valid? validation_message = "Buyer 1’s age must be between 16 and 110." - expect(parser.errors[:field_28]).to include validation_message + expect(parser.errors[:field_29]).to include validation_message end end context "when buyer 1 is over 16 but has ecstat as child" do - let(:attributes) { valid_attributes.merge({ field_28: "17", field_32: "9" }) } + let(:attributes) { valid_attributes.merge({ field_29: "17", field_35: "9" }) } it "a custom validation is applied" do parser.valid? - expect(parser.errors[:field_32]).to include I18n.t("validations.sales.2026.bulk_upload.ecstat1.buyer_cannot_be_over_16_and_child") - expect(parser.errors[:field_28]).to include I18n.t("validations.sales.2026.bulk_upload.age1.buyer_cannot_be_over_16_and_child") + expect(parser.errors[:field_35]).to include I18n.t("validations.sales.2026.bulk_upload.ecstat1.buyer_cannot_be_over_16_and_child") + expect(parser.errors[:field_29]).to include I18n.t("validations.sales.2026.bulk_upload.age1.buyer_cannot_be_over_16_and_child") end end end - describe "#field_33" do # will buyer1 live in property? + describe "#field_36" do # will buyer1 live in property? context "when not a possible value" do - let(:attributes) { valid_attributes.merge({ field_10: "2", field_33: "3" }) } + let(:attributes) { valid_attributes.merge({ field_10: "2", field_36: "3" }) } it "is not valid" do parser.valid? - expect(parser.errors).to include(:field_33) + expect(parser.errors).to include(:field_36) end end end - describe "#field_109" do # staircasing mortgageused + describe "#field_122" do # staircasing mortgageused context "when invalid value" do - let(:attributes) { setup_section_params.merge(field_109: "4") } + let(:attributes) { setup_section_params.merge(field_122: "4") } it "returns correct errors" do parser.valid? - expect(parser.errors[:field_109]).to include(I18n.t("validations.sales.2026.bulk_upload.invalid_option", question: "was a mortgage used for this staircasing transaction?")) + expect(parser.errors[:field_122]).to include(I18n.t("validations.sales.2026.bulk_upload.invalid_option", question: "was a mortgage used for this staircasing transaction?")) parser.log.blank_invalid_non_setup_fields! parser.log.save! @@ -1315,11 +1315,11 @@ RSpec.describe BulkUpload::Sales::Year2026::RowParser do end context "when value is 3 and stairowned is not 100" do - let(:attributes) { setup_section_params.merge(field_109: "3", field_10: "1", field_96: "50", field_97: "99", field_120: nil) } + let(:attributes) { setup_section_params.merge(field_122: "3", field_10: "1", field_109: "50", field_110: "99", field_135: nil) } it "returns correct errors" do parser.valid? - expect(parser.errors[:field_109]).to include("The percentage owned has to be 100% if the mortgage used is 'Don’t know'") + expect(parser.errors[:field_122]).to include("The percentage owned has to be 100% if the mortgage used is 'Don’t know'") parser.log.blank_invalid_non_setup_fields! parser.log.save! @@ -1328,35 +1328,35 @@ RSpec.describe BulkUpload::Sales::Year2026::RowParser do end context "when value is 3 and stairowned is not answered" do - let(:attributes) { setup_section_params.merge(field_109: "3", field_10: "1", field_96: "50", field_97: nil, field_120: nil) } + let(:attributes) { setup_section_params.merge(field_122: "3", field_10: "1", field_109: "50", field_110: nil, field_135: nil) } it "does not add errors" do parser.valid? - expect(parser.errors[:field_109]).to be_empty + expect(parser.errors[:field_122]).to be_empty end end context "when value is 3 and stairowned is 100" do - let(:attributes) { setup_section_params.merge(field_109: "3", field_10: "1", field_96: "50", field_97: "100", field_120: nil) } + let(:attributes) { setup_section_params.merge(field_122: "3", field_10: "1", field_109: "50", field_110: "100", field_135: nil) } it "does not add errors and sets mortgage used to 3" do parser.valid? expect(parser.log.mortgageused).to eq(3) expect(parser.log.stairowned).to eq(100) expect(parser.log.deposit).to be_nil - expect(parser.errors[:field_109]).to be_empty - expect(parser.errors[:field_120]).to be_empty + expect(parser.errors[:field_122]).to be_empty + expect(parser.errors[:field_135]).to be_empty end end end - describe "#field_88" do # shared ownership mortgageused + describe "#field_101" do # shared ownership mortgageused context "when invalid value" do - let(:attributes) { setup_section_params.merge(field_10: "2", field_88: "4") } + let(:attributes) { setup_section_params.merge(field_10: "2", field_101: "4") } it "returns correct errors" do parser.valid? - expect(parser.errors[:field_88]).to include(I18n.t("validations.sales.2026.bulk_upload.invalid_option", question: "was a mortgage used for the purchase of this property? - Shared ownership.")) + expect(parser.errors[:field_101]).to include(I18n.t("validations.sales.2026.bulk_upload.invalid_option", question: "was a mortgage used for the purchase of this property? - Shared ownership.")) parser.log.blank_invalid_non_setup_fields! parser.log.save! @@ -1365,11 +1365,11 @@ RSpec.describe BulkUpload::Sales::Year2026::RowParser do end context "when value is 3 and stairowned is not answered" do - let(:attributes) { setup_section_params.merge(field_88: "3", field_10: "2", field_96: "50", field_97: nil, field_120: nil) } + let(:attributes) { setup_section_params.merge(field_101: "3", field_10: "2", field_109: "50", field_110: nil, field_135: nil) } it "returns correct errors" do parser.valid? - expect(parser.errors[:field_88]).to include(I18n.t("validations.invalid_option", question: "was a mortgage used for the purchase of this property?")) + expect(parser.errors[:field_101]).to include(I18n.t("validations.invalid_option", question: "was a mortgage used for the purchase of this property?")) parser.log.blank_invalid_non_setup_fields! parser.log.save! @@ -1378,7 +1378,7 @@ RSpec.describe BulkUpload::Sales::Year2026::RowParser do end context "with non staircasing mortgage error" do - let(:attributes) { setup_section_params.merge(field_9: "30", field_88: "1", field_89: "10000", field_91: "5000", field_86: "30000", field_87: "28", field_10: "2") } + let(:attributes) { setup_section_params.merge(field_9: "30", field_101: "1", field_102: "10000", field_104: "5000", field_99: "30000", field_100: "28", field_10: "2") } it "does not add a BU error on type (because it's a setup field and would block log creation)" do parser.valid? @@ -1387,31 +1387,31 @@ RSpec.describe BulkUpload::Sales::Year2026::RowParser do it "includes errors on other related fields" do parser.valid? - expect(parser.errors[:field_89]).to include("The mortgage (£10,000.00) and cash deposit (£5,000.00) added together is £15,000.00.

The full purchase price (£30,000.00) multiplied by the percentage equity stake purchased (28.0%) is £8,400.00.

These two amounts should be the same.") - expect(parser.errors[:field_91]).to include("The mortgage (£10,000.00) and cash deposit (£5,000.00) added together is £15,000.00.

The full purchase price (£30,000.00) multiplied by the percentage equity stake purchased (28.0%) is £8,400.00.

These two amounts should be the same.") - expect(parser.errors[:field_86]).to include("The mortgage (£10,000.00) and cash deposit (£5,000.00) added together is £15,000.00.

The full purchase price (£30,000.00) multiplied by the percentage equity stake purchased (28.0%) is £8,400.00.

These two amounts should be the same.") - expect(parser.errors[:field_87]).to include("The mortgage (£10,000.00) and cash deposit (£5,000.00) added together is £15,000.00.

The full purchase price (£30,000.00) multiplied by the percentage equity stake purchased (28.0%) is £8,400.00.

These two amounts should be the same.") + expect(parser.errors[:field_102]).to include("The mortgage (£10,000.00) and cash deposit (£5,000.00) added together is £15,000.00.

The full purchase price (£30,000.00) multiplied by the percentage equity stake purchased (28.0%) is £8,400.00.

These two amounts should be the same.") + expect(parser.errors[:field_104]).to include("The mortgage (£10,000.00) and cash deposit (£5,000.00) added together is £15,000.00.

The full purchase price (£30,000.00) multiplied by the percentage equity stake purchased (28.0%) is £8,400.00.

These two amounts should be the same.") + expect(parser.errors[:field_99]).to include("The mortgage (£10,000.00) and cash deposit (£5,000.00) added together is £15,000.00.

The full purchase price (£30,000.00) multiplied by the percentage equity stake purchased (28.0%) is £8,400.00.

These two amounts should be the same.") + expect(parser.errors[:field_100]).to include("The mortgage (£10,000.00) and cash deposit (£5,000.00) added together is £15,000.00.

The full purchase price (£30,000.00) multiplied by the percentage equity stake purchased (28.0%) is £8,400.00.

These two amounts should be the same.") end it "does not add errors to other ownership type fields" do parser.valid? - expect(parser.errors[:field_117]).to be_empty + expect(parser.errors[:field_132]).to be_empty + expect(parser.errors[:field_135]).to be_empty + expect(parser.errors[:field_128]).to be_empty expect(parser.errors[:field_120]).to be_empty - expect(parser.errors[:field_113]).to be_empty - expect(parser.errors[:field_107]).to be_empty - expect(parser.errors[:field_108]).to be_empty - expect(parser.errors[:field_116]).to be_empty - expect(parser.errors[:field_109]).to be_empty + expect(parser.errors[:field_121]).to be_empty + expect(parser.errors[:field_131]).to be_empty + expect(parser.errors[:field_122]).to be_empty end end end - describe "#field_116" do - let(:attributes) { valid_attributes.merge({ field_8: "2", field_11: "9", field_116: "3" }) } + describe "#field_131" do + let(:attributes) { valid_attributes.merge({ field_8: "2", field_11: "9", field_131: "3" }) } it "does not allow 3 (don't know) as an option for discounted ownership" do parser.valid? - expect(parser.errors[:field_116]).to include(I18n.t("validations.invalid_option", question: "was a mortgage used for the purchase of this property?")) + expect(parser.errors[:field_131]).to include(I18n.t("validations.invalid_option", question: "was a mortgage used for the purchase of this property?")) parser.log.blank_invalid_non_setup_fields! parser.log.save! @@ -1419,31 +1419,31 @@ RSpec.describe BulkUpload::Sales::Year2026::RowParser do end context "when validate_discounted_ownership_value is triggered" do - let(:attributes) { setup_section_params.merge(field_113: 100, field_120: 100, field_8: 2, field_10: 2, field_11: 9, field_116: 2, field_115: 10) } + let(:attributes) { setup_section_params.merge(field_128: 100, field_135: 100, field_8: 2, field_10: 2, field_11: 9, field_131: 2, field_130: 10) } it "only adds errors to the discounted ownership field" do parser.valid? - expect(parser.errors[:field_88]).to be_empty - expect(parser.errors[:field_117]).to include("The mortgage and cash deposit (£100.00) added together is £100.00.

The full purchase price (£100.00) subtracted by the sum of the full purchase price (£100.00) multiplied by the percentage discount (10.0%) is £90.00.

These two amounts should be the same.") - expect(parser.errors[:field_126]).to be_empty + expect(parser.errors[:field_101]).to be_empty + expect(parser.errors[:field_132]).to include("The mortgage and cash deposit (£100.00) added together is £100.00.

The full purchase price (£100.00) subtracted by the sum of the full purchase price (£100.00) multiplied by the percentage discount (10.0%) is £90.00.

These two amounts should be the same.") + expect(parser.errors[:field_41]).to be_empty end end end describe "soft validations" do context "when soft validation is triggered" do - let(:attributes) { valid_attributes.merge({ field_10: 2, field_28: 22, field_32: 5 }) } + let(:attributes) { valid_attributes.merge({ field_10: 2, field_29: 22, field_35: 5 }) } it "adds an error to the relevant fields" do parser.valid? - expect(parser.errors.where(:field_28, category: :soft_validation)).to be_present - expect(parser.errors.where(:field_32, category: :soft_validation)).to be_present + expect(parser.errors.where(:field_29, category: :soft_validation)).to be_present + expect(parser.errors.where(:field_35, category: :soft_validation)).to be_present end it "populates with correct error message" do parser.valid? - expect(parser.errors.where(:field_28, category: :soft_validation).first.message).to eql("You told us this person is aged 22 years and retired. The minimum expected retirement age in England is 66.") - expect(parser.errors.where(:field_32, category: :soft_validation).first.message).to eql("You told us this person is aged 22 years and retired. The minimum expected retirement age in England is 66.") + expect(parser.errors.where(:field_29, category: :soft_validation).first.message).to eql("You told us this person is aged 22 years and retired. The minimum expected retirement age in England is 66.") + expect(parser.errors.where(:field_35, category: :soft_validation).first.message).to eql("You told us this person is aged 22 years and retired. The minimum expected retirement age in England is 66.") end end end @@ -1460,16 +1460,16 @@ RSpec.describe BulkUpload::Sales::Year2026::RowParser do end end - describe "field_90" do - context "when field_90 is a number" do - let(:field_90_number_attributes) { valid_attributes.merge({ field_90: 20 }) } + describe "field_103" do + context "when field_103 is a number" do + let(:field_90_number_attributes) { valid_attributes.merge({ field_103: 20 }) } context "and buyer was interviewed" do let(:attributes) { field_90_number_attributes.merge({ field_14: 2 }) } it "does not add an error" do parser.valid? - expect(parser.errors.where(:field_90)).not_to be_present + expect(parser.errors.where(:field_103)).not_to be_present end end @@ -1478,20 +1478,20 @@ RSpec.describe BulkUpload::Sales::Year2026::RowParser do it "does not add an error" do parser.valid? - expect(parser.errors.where(:field_90)).not_to be_present + expect(parser.errors.where(:field_103)).not_to be_present end end end - context "when field_90 is R" do - let(:field_90_number_attributes) { valid_attributes.merge({ field_90: "R" }) } + context "when field_103 is R" do + let(:field_90_number_attributes) { valid_attributes.merge({ field_103: "R" }) } context "and buyer was interviewed" do let(:attributes) { field_90_number_attributes.merge({ field_14: 2 }) } it "adds an error" do parser.valid? - expect(parser.errors.where(:field_90)).to be_present + expect(parser.errors.where(:field_103)).to be_present end end @@ -1500,20 +1500,20 @@ RSpec.describe BulkUpload::Sales::Year2026::RowParser do it "does not add an error" do parser.valid? - expect(parser.errors.where(:field_90)).not_to be_present + expect(parser.errors.where(:field_103)).not_to be_present end end end - context "when field_90 is neither a number nor R" do - let(:field_90_number_attributes) { valid_attributes.merge({ field_90: "something" }) } + context "when field_103 is neither a number nor R" do + let(:field_90_number_attributes) { valid_attributes.merge({ field_103: "something" }) } context "and buyer was interviewed" do let(:attributes) { field_90_number_attributes.merge({ field_14: 2 }) } it "adds an error" do parser.valid? - expect(parser.errors.where(:field_90)).to be_present + expect(parser.errors.where(:field_103)).to be_present end end @@ -1522,7 +1522,7 @@ RSpec.describe BulkUpload::Sales::Year2026::RowParser do it "adds an error" do parser.valid? - expect(parser.errors.where(:field_90)).to be_present + expect(parser.errors.where(:field_103)).to be_present end end end @@ -1607,8 +1607,8 @@ RSpec.describe BulkUpload::Sales::Year2026::RowParser do end describe "#ethnic_group" do - context "when field_30 is 20" do - let(:attributes) { setup_section_params.merge({ field_30: "20" }) } + context "when field_33 is 20" do + let(:attributes) { setup_section_params.merge({ field_33: "20" }) } it "is correctly set" do expect(parser.log.ethnic_group).to be(0) @@ -1617,14 +1617,14 @@ RSpec.describe BulkUpload::Sales::Year2026::RowParser do end describe "#ethnic_group2" do - let(:attributes) { setup_section_params.merge({ field_37: "1" }) } + let(:attributes) { setup_section_params.merge({ field_42: "1" }) } it "is correctly set" do expect(parser.log.ethnic_group2).to be(0) end - context "when field_37 is 20" do - let(:attributes) { setup_section_params.merge({ field_37: "20" }) } + context "when field_42 is 20" do + let(:attributes) { setup_section_params.merge({ field_42: "20" }) } it "is correctly set" do expect(parser.log.ethnic_group2).to be(0) @@ -1633,7 +1633,7 @@ RSpec.describe BulkUpload::Sales::Year2026::RowParser do end describe "#ethnicbuy2" do - let(:attributes) { setup_section_params.merge({ field_37: "1" }) } + let(:attributes) { setup_section_params.merge({ field_42: "1" }) } it "is correctly set" do expect(parser.log.ethnicbuy2).to be(1) @@ -1641,8 +1641,8 @@ RSpec.describe BulkUpload::Sales::Year2026::RowParser do end describe "#nationality_all" do - context "when field_31 is a 3 digit nationality code" do - let(:attributes) { setup_section_params.merge({ field_31: "036" }) } + context "when field_34 is a 3 digit nationality code" do + let(:attributes) { setup_section_params.merge({ field_34: "036" }) } it "is correctly set" do expect(parser.log.nationality_all).to be(36) @@ -1650,8 +1650,8 @@ RSpec.describe BulkUpload::Sales::Year2026::RowParser do end end - context "when field_31 is a nationality code without the trailing 0s" do - let(:attributes) { setup_section_params.merge({ field_31: "36" }) } + context "when field_34 is a nationality code without the trailing 0s" do + let(:attributes) { setup_section_params.merge({ field_34: "36" }) } it "is correctly set" do expect(parser.log.nationality_all).to be(36) @@ -1659,8 +1659,8 @@ RSpec.describe BulkUpload::Sales::Year2026::RowParser do end end - context "when field_31 is a nationality code with trailing 0s" do - let(:attributes) { setup_section_params.merge({ field_31: "0036" }) } + context "when field_34 is a nationality code with trailing 0s" do + let(:attributes) { setup_section_params.merge({ field_34: "0036" }) } it "is correctly set" do expect(parser.log.nationality_all).to be(36) @@ -1668,8 +1668,8 @@ RSpec.describe BulkUpload::Sales::Year2026::RowParser do end end - context "when field_31 is 0" do - let(:attributes) { setup_section_params.merge({ field_31: "0" }) } + context "when field_34 is 0" do + let(:attributes) { setup_section_params.merge({ field_34: "0" }) } it "is correctly set" do expect(parser.log.nationality_all).to be(0) @@ -1677,8 +1677,8 @@ RSpec.describe BulkUpload::Sales::Year2026::RowParser do end end - context "when field_31 is 000" do - let(:attributes) { setup_section_params.merge({ field_31: "000" }) } + context "when field_34 is 000" do + let(:attributes) { setup_section_params.merge({ field_34: "000" }) } it "is correctly set" do expect(parser.log.nationality_all).to be(0) @@ -1686,8 +1686,8 @@ RSpec.describe BulkUpload::Sales::Year2026::RowParser do end end - context "when field_31 is 0000" do - let(:attributes) { setup_section_params.merge({ field_31: "0000" }) } + context "when field_34 is 0000" do + let(:attributes) { setup_section_params.merge({ field_34: "0000" }) } it "is correctly set" do expect(parser.log.nationality_all).to be(0) @@ -1695,8 +1695,8 @@ RSpec.describe BulkUpload::Sales::Year2026::RowParser do end end - context "when field_31 is 826" do - let(:attributes) { setup_section_params.merge({ field_31: "826" }) } + context "when field_34 is 826" do + let(:attributes) { setup_section_params.merge({ field_34: "826" }) } it "is correctly set" do expect(parser.log.nationality_all).to be(826) @@ -1704,8 +1704,8 @@ RSpec.describe BulkUpload::Sales::Year2026::RowParser do end end - context "when field_31 is 826 with trailing 0s" do - let(:attributes) { setup_section_params.merge({ field_31: "0826" }) } + context "when field_34 is 826 with trailing 0s" do + let(:attributes) { setup_section_params.merge({ field_34: "0826" }) } it "is correctly set" do expect(parser.log.nationality_all).to be(826) @@ -1713,21 +1713,21 @@ RSpec.describe BulkUpload::Sales::Year2026::RowParser do end end - context "when field_31 is not a valid option" do - let(:attributes) { setup_section_params.merge({ field_31: "123123" }) } + context "when field_34 is not a valid option" do + let(:attributes) { setup_section_params.merge({ field_34: "123123" }) } it "is correctly set" do parser.valid? expect(parser.log.nationality_all).to be_nil expect(parser.log.nationality_all_group).to be_nil - expect(parser.errors["field_31"]).to include(I18n.t("validations.sales.2026.bulk_upload.nationality.invalid")) + expect(parser.errors["field_34"]).to include(I18n.t("validations.sales.2026.bulk_upload.nationality.invalid")) end end end describe "#nationality_all_buyer2" do - context "when field_38 is a 3 digit nationality code" do - let(:attributes) { setup_section_params.merge({ field_38: "036" }) } + context "when field_43 is a 3 digit nationality code" do + let(:attributes) { setup_section_params.merge({ field_43: "036" }) } it "is correctly set" do expect(parser.log.nationality_all_buyer2).to be(36) @@ -1735,8 +1735,8 @@ RSpec.describe BulkUpload::Sales::Year2026::RowParser do end end - context "when field_38 is a nationality code without the trailing 0s" do - let(:attributes) { setup_section_params.merge({ field_38: "36" }) } + context "when field_43 is a nationality code without the trailing 0s" do + let(:attributes) { setup_section_params.merge({ field_43: "36" }) } it "is correctly set" do expect(parser.log.nationality_all_buyer2).to be(36) @@ -1744,8 +1744,8 @@ RSpec.describe BulkUpload::Sales::Year2026::RowParser do end end - context "when field_38 is a nationality code with trailing 0s" do - let(:attributes) { setup_section_params.merge({ field_38: "0036" }) } + context "when field_43 is a nationality code with trailing 0s" do + let(:attributes) { setup_section_params.merge({ field_43: "0036" }) } it "is correctly set" do expect(parser.log.nationality_all_buyer2).to be(36) @@ -1753,8 +1753,8 @@ RSpec.describe BulkUpload::Sales::Year2026::RowParser do end end - context "when field_38 is 0" do - let(:attributes) { setup_section_params.merge({ field_38: "0" }) } + context "when field_43 is 0" do + let(:attributes) { setup_section_params.merge({ field_43: "0" }) } it "is correctly set" do expect(parser.log.nationality_all_buyer2).to be(0) @@ -1762,8 +1762,8 @@ RSpec.describe BulkUpload::Sales::Year2026::RowParser do end end - context "when field_38 is 000" do - let(:attributes) { setup_section_params.merge({ field_38: "000" }) } + context "when field_43 is 000" do + let(:attributes) { setup_section_params.merge({ field_43: "000" }) } it "is correctly set" do expect(parser.log.nationality_all_buyer2).to be(0) @@ -1771,8 +1771,8 @@ RSpec.describe BulkUpload::Sales::Year2026::RowParser do end end - context "when field_38 is 0000" do - let(:attributes) { setup_section_params.merge({ field_38: "0000" }) } + context "when field_43 is 0000" do + let(:attributes) { setup_section_params.merge({ field_43: "0000" }) } it "is correctly set" do expect(parser.log.nationality_all_buyer2).to be(0) @@ -1780,8 +1780,8 @@ RSpec.describe BulkUpload::Sales::Year2026::RowParser do end end - context "when field_38 is 826" do - let(:attributes) { setup_section_params.merge({ field_38: "826" }) } + context "when field_43 is 826" do + let(:attributes) { setup_section_params.merge({ field_43: "826" }) } it "is correctly set" do expect(parser.log.nationality_all_buyer2).to be(826) @@ -1789,8 +1789,8 @@ RSpec.describe BulkUpload::Sales::Year2026::RowParser do end end - context "when field_38 is 826 with trailing 0s" do - let(:attributes) { setup_section_params.merge({ field_38: "0826" }) } + context "when field_43 is 826 with trailing 0s" do + let(:attributes) { setup_section_params.merge({ field_43: "0826" }) } it "is correctly set" do expect(parser.log.nationality_all_buyer2).to be(826) @@ -1798,20 +1798,20 @@ RSpec.describe BulkUpload::Sales::Year2026::RowParser do end end - context "when field_38 is not a valid option" do - let(:attributes) { setup_section_params.merge({ field_38: "123123" }) } + context "when field_43 is not a valid option" do + let(:attributes) { setup_section_params.merge({ field_43: "123123" }) } it "is correctly set" do parser.valid? expect(parser.log.nationality_all_buyer2).to be_nil expect(parser.log.nationality_all_buyer2_group).to be_nil - expect(parser.errors["field_38"]).to include(I18n.t("validations.sales.2026.bulk_upload.nationality.invalid")) + expect(parser.errors["field_43"]).to include(I18n.t("validations.sales.2026.bulk_upload.nationality.invalid")) end end end describe "#buy2living" do - let(:attributes) { setup_section_params.merge({ field_63: "1" }) } + let(:attributes) { setup_section_params.merge({ field_76: "1" }) } it "is correctly set" do expect(parser.log.buy2living).to be(1) @@ -1819,7 +1819,7 @@ RSpec.describe BulkUpload::Sales::Year2026::RowParser do end describe "#prevtenbuy2" do - let(:attributes) { setup_section_params.merge({ field_64: "R" }) } + let(:attributes) { setup_section_params.merge({ field_77: "R" }) } it "is correctly set" do expect(parser.log.prevtenbuy2).to be(0) @@ -1827,7 +1827,7 @@ RSpec.describe BulkUpload::Sales::Year2026::RowParser do end describe "#hhregres" do - let(:attributes) { setup_section_params.merge({ field_65: "1" }) } + let(:attributes) { setup_section_params.merge({ field_78: "1" }) } it "is correctly set" do expect(parser.log.hhregres).to be(1) @@ -1835,7 +1835,7 @@ RSpec.describe BulkUpload::Sales::Year2026::RowParser do end describe "#hhregresstill" do - let(:attributes) { setup_section_params.merge({ field_66: "4" }) } + let(:attributes) { setup_section_params.merge({ field_79: "4" }) } it "is correctly set" do expect(parser.log.hhregresstill).to be(4) @@ -1843,7 +1843,7 @@ RSpec.describe BulkUpload::Sales::Year2026::RowParser do end describe "#prevshared" do - let(:attributes) { setup_section_params.merge({ field_77: "3" }) } + let(:attributes) { setup_section_params.merge({ field_90: "3" }) } it "is correctly set" do expect(parser.log.prevshared).to be(3) @@ -1851,7 +1851,7 @@ RSpec.describe BulkUpload::Sales::Year2026::RowParser do end describe "#staircasesale" do - let(:attributes) { setup_section_params.merge({ field_98: "1" }) } + let(:attributes) { setup_section_params.merge({ field_111: "1" }) } it "is correctly set" do expect(parser.log.staircasesale).to be(1) @@ -1869,7 +1869,7 @@ RSpec.describe BulkUpload::Sales::Year2026::RowParser do context "when shared ownership" do context "when prevten is a social housing type" do - let(:attributes) { valid_attributes.merge({ field_8: "1", field_58: "1" }) } + let(:attributes) { valid_attributes.merge({ field_8: "1", field_71: "1" }) } it "is set to yes" do expect(parser.log.soctenant).to be(1) @@ -1878,7 +1878,7 @@ RSpec.describe BulkUpload::Sales::Year2026::RowParser do context "when prevten is not a social housing type" do context "and prevtenbuy2 is a social housing type" do - let(:attributes) { valid_attributes.merge({ field_8: "1", field_58: "3", field_64: "2" }) } + let(:attributes) { valid_attributes.merge({ field_8: "1", field_71: "3", field_77: "2" }) } it "is set to yes" do expect(parser.log.soctenant).to be(1) @@ -1886,7 +1886,7 @@ RSpec.describe BulkUpload::Sales::Year2026::RowParser do end context "and prevtenbuy2 is not a social housing type" do - let(:attributes) { valid_attributes.merge({ field_8: "1", field_58: "3", field_64: "4" }) } + let(:attributes) { valid_attributes.merge({ field_8: "1", field_71: "3", field_77: "4" }) } it "is set to no" do expect(parser.log.soctenant).to be(2) @@ -1894,7 +1894,7 @@ RSpec.describe BulkUpload::Sales::Year2026::RowParser do end context "and prevtenbuy2 is blank" do - let(:attributes) { valid_attributes.merge({ field_8: "1", field_58: "3", field_64: nil }) } + let(:attributes) { valid_attributes.merge({ field_8: "1", field_71: "3", field_77: nil }) } it "is set to no" do expect(parser.log.soctenant).to be(2) @@ -1905,7 +1905,7 @@ RSpec.describe BulkUpload::Sales::Year2026::RowParser do end describe "with living before purchase years for shared ownership more than 0" do - let(:attributes) { setup_section_params.merge({ field_8: "1", field_79: "1" }) } + let(:attributes) { setup_section_params.merge({ field_8: "1", field_92: "1" }) } it "is sets living before purchase asked to yes and sets the correct living before purchase years" do expect(parser.log.proplen_asked).to be(0) @@ -1914,7 +1914,7 @@ RSpec.describe BulkUpload::Sales::Year2026::RowParser do end describe "with living before purchase years for discounted ownership more than 0" do - let(:attributes) { setup_section_params.merge({ field_8: "2", field_112: "1" }) } + let(:attributes) { setup_section_params.merge({ field_8: "2", field_127: "1" }) } it "is sets living before purchase asked to yes and sets the correct living before purchase years" do expect(parser.log.proplen_asked).to be(0) @@ -1923,7 +1923,7 @@ RSpec.describe BulkUpload::Sales::Year2026::RowParser do end describe "with living before purchase years for shared ownership set to 0" do - let(:attributes) { setup_section_params.merge({ field_8: "1", field_79: "0" }) } + let(:attributes) { setup_section_params.merge({ field_8: "1", field_92: "0" }) } it "is sets living before purchase asked to no" do expect(parser.log.proplen_asked).to be(1) @@ -1932,7 +1932,7 @@ RSpec.describe BulkUpload::Sales::Year2026::RowParser do end describe "with living before purchase 0 years for discounted ownership set to 0" do - let(:attributes) { setup_section_params.merge({ field_8: "2", field_112: "0" }) } + let(:attributes) { setup_section_params.merge({ field_8: "2", field_127: "0" }) } it "is sets living before purchase asked to no" do expect(parser.log.proplen_asked).to be(1) @@ -1941,7 +1941,7 @@ RSpec.describe BulkUpload::Sales::Year2026::RowParser do end context "when mscharge is given, but is set to 0 for shared ownership" do - let(:attributes) { valid_attributes.merge(field_94: "0") } + let(:attributes) { valid_attributes.merge(field_107: "0") } it "does not override variables correctly" do log = parser.log @@ -1951,7 +1951,7 @@ RSpec.describe BulkUpload::Sales::Year2026::RowParser do end context "when mscharge is given, but is set to 0 for discounted ownership" do - let(:attributes) { valid_attributes.merge(field_8: "2", field_121: "0") } + let(:attributes) { valid_attributes.merge(field_8: "2", field_136: "0") } it "does not override variables correctly" do log = parser.log @@ -2034,8 +2034,8 @@ RSpec.describe BulkUpload::Sales::Year2026::RowParser do end describe "mortlen amd mortlen_known" do - context "when field_90 is a number" do - let(:field_90_number_attributes) { valid_attributes.merge({ field_90: 20 }) } + context "when field_103 is a number" do + let(:field_90_number_attributes) { valid_attributes.merge({ field_103: 20 }) } context "and buyer was interviewed" do let(:attributes) { field_90_number_attributes.merge({ field_14: 2 }) } @@ -2066,8 +2066,8 @@ RSpec.describe BulkUpload::Sales::Year2026::RowParser do end end - context "when field_90 is R" do - let(:field_90_number_attributes) { valid_attributes.merge({ field_90: "R" }) } + context "when field_103 is R" do + let(:field_90_number_attributes) { valid_attributes.merge({ field_103: "R" }) } context "and buyer was not interviewed" do let(:attributes) { field_90_number_attributes.merge({ field_14: 1 }) }