diff --git a/app/services/bulk_upload/sales/year2024/csv_parser.rb b/app/services/bulk_upload/sales/year2024/csv_parser.rb index aa0a5f729..fa2b12b39 100644 --- a/app/services/bulk_upload/sales/year2024/csv_parser.rb +++ b/app/services/bulk_upload/sales/year2024/csv_parser.rb @@ -3,7 +3,7 @@ require "csv" class BulkUpload::Sales::Year2024::CsvParser include CollectionTimeHelper - MAX_COLUMNS = 142 + MAX_COLUMNS = 132 FORM_YEAR = 2024 attr_reader :path @@ -58,7 +58,7 @@ class BulkUpload::Sales::Year2024::CsvParser private def default_field_numbers - [6, 3, 4, 5, nil, 28, 30, 38, 47, 51, 55, 59, 31, 39, 48, 52, 56, 60, 37, 46, 50, 54, 58, 35, 43, 49, 53, 57, 61, 32, 33, 78, 80, 79, 81, 83, 84, nil, 62, 66, 64, 65, 63, 67, 69, 70, 68, 76, 77, 16, 17, 18, 26, 24, 25, 27, 8, 91, 95, 96, 97, 92, 93, 94, 98, 100, 101, 103, 104, 106, 110, 111, 112, 113, 114, 9, 116, 117, 118, 120, 124, 125, 126, 10, 11, nil, 127, 129, 133, 134, 135, 1, 2, nil, 73, nil, 75, 107, 108, 121, 122, 130, 131, 82, 109, 123, 132, 115, 15, 86, 87, 29, 7, 12, 13, 14, 36, 44, 45, 88, 89, 102, 105, 119, 128, 19, 20, 21, 22, 23, 34, 40, 41, 42, 71, 72, 74, 85, 90, 99].map do |number| + (1..131).map do |number| if number.to_s.match?(/^[0-9]+$/) "field_#{number}" else diff --git a/app/services/bulk_upload/sales/year2024/row_parser.rb b/app/services/bulk_upload/sales/year2024/row_parser.rb index 96b075bc6..f36c1be45 100644 --- a/app/services/bulk_upload/sales/year2024/row_parser.rb +++ b/app/services/bulk_upload/sales/year2024/row_parser.rb @@ -6,42 +6,41 @@ class BulkUpload::Sales::Year2024::RowParser QUESTIONS = { field_1: "Which organisation owned this property before the sale?", field_2: "Which organisation is reporting this sale?", - field_2: "Username", - field_3: "What is the day of the sale completion date? - DD", - field_4: "What is the month of the sale completion date? - MM", - field_5: "What is the year of the sale completion date? - YY", - field_6: "What is the purchaser code?", - field_7: "Was this purchase made through an ownership scheme?", - field_8: "What is the type of shared ownership sale?", - field_9: "What is the type of discounted ownership sale?", - field_10: "What is the type of outright sale?", - - field_11: "If 'other', what is the 'other' type?", - field_12: "Is the buyer a company?", - field_13: "Will the buyers live in the property?", - field_14: "Is this a joint purchase?", - field_15: "Are there more than two joint purchasers of this property?", - field_16: "How many bedrooms does the property have?", - field_17: "What type of unit is the property?", - field_18: "Which type of bulding is the property?", - field_19: "If known, enter this property's UPRN", - field_20: "Address line 1", - - field_21: "Address line 2", - field_22: "Town or city", - field_23: "County", - field_24: "Part 1 of postcode of property", - field_25: "Part 2 of postcode of property", - field_26: "What is the local authority of the property?", - field_27: "Is the property built or adapted to wheelchair user standards?", - field_28: "Was the buyer interviewed for any of the answers you will provide on this log?", - field_29: "Data Protection question", - field_30: "Age of buyer 1", - - field_31: "Gender identity of buyer 1", - field_32: "What is buyer 1's ethnic group?", - field_33: "What is buyer 1's nationality?", - field_34: "If 'Any other country', what is buyer 1's nationality?", + field_3: "Username", + field_4: "What is the day of the sale completion date? - DD", + field_5: "What is the month of the sale completion date? - MM", + field_6: "What is the year of the sale completion date? - YY", + field_7: "What is the purchaser code?", + field_8: "Was this purchase made through an ownership scheme?", + field_9: "What is the type of shared ownership sale?", + field_10: "What is the type of discounted ownership sale?", + field_11: "What is the type of outright sale?", + + field_12: "If 'other', what is the 'other' type?", + field_13: "Is the buyer a company?", + field_14: "Will the buyers live in the property?", + field_15: "Is this a joint purchase?", + field_16: "Are there more than two joint purchasers of this property?", + field_17: "Was the buyer interviewed for any of the answers you will provide on this log?", + field_18: "Data Protection question", + field_19: "How many bedrooms does the property have?", + field_20: "What type of unit is the property?", + field_21: "Which type of bulding is the property?", + field_22: "If known, enter this property's UPRN", + field_23: "Address line 1", + + field_24: "Address line 2", + field_25: "Town or city", + field_26: "County", + field_27: "Part 1 of postcode of property", + field_28: "Part 2 of postcode of property", + field_29: "What is the local authority of the property?", + field_30: "Is the property built or adapted to wheelchair user standards?", + field_31: "Age of buyer 1", + + field_32: "Gender identity of buyer 1", + 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: "Relationship to buyer 1 for person 2", @@ -50,109 +49,105 @@ class BulkUpload::Sales::Year2024::RowParser field_40: "Which of the following best describes buyer 2's ethnic background?", field_41: "What is buyer 2's nationality?", - field_42: "If 'Any other country', what is buyer 2's nationality?", - field_43: "What is buyer 2 or person 2's working situation?", - field_44: "Will buyer 2 live in the property?", - field_45: "Besides the buyers, how many people will live in the property?", - field_46: "Relationship to buyer 1 for person 3", - field_47: "Age of person 3", - field_48: "Gender identity of person 3", - field_49: "Working situation of person 3", - field_50: "Relationship to buyer 1 for person 4", - - field_51: "Age of person 4", - field_52: "Gender identity of person 4", - field_53: "Working situation of person 4", - field_54: "Relationship to buyer 1 for person 5", - field_55: "Age of person 5", - field_56: "Gender identity of person 5", - field_57: "Working situation of person 5", - field_58: "Relationship to buyer 1 for person 6", - field_59: "Age of person 6", - field_60: "Gender identity of person 6", - - field_61: "Working situation of person 6", - field_62: "What was buyer 1's previous tenure?", - field_63: "Do you know the postcode of buyer 1's last settled home?", - field_64: "Part 1 of postcode of buyer 1's last settled home", - field_65: "Part 2 of postcode of buyer 1's last settled home", - field_66: "What is the local authority of buyer 1's last settled home?", - field_67: "Was the buyer registered with their PRP (HA)?", - field_68: "Was the buyer registered with another PRP (HA)?", - field_69: "Was the buyer registered with the local authority?", - field_70: "Was the buyer registered with a Help to Buy agent?", - - field_71: "At the time of purchase, was buyer 2 living at the same address as buyer 1?", - field_72: "What was buyer 2's previous tenure?", - field_73: "Has the buyer ever served in the UK Armed Forces and for how long?", - field_74: "Is the buyer still serving in the UK armed forces?", - field_75: "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_76: "Does anyone in the household consider themselves to have a disability?", - field_77: "Does anyone in the household use a wheelchair?", - field_78: "What is buyer 1's gross annual income?", - field_79: "Was buyer 1's income used for a mortgage application?", - field_80: "What is buyer 2's gross annual income?", - - field_81: "Was buyer 2's income used for a mortgage application?", - field_82: "Were the buyers receiving any of these housing-related benefits immediately before buying this property?", - field_83: "What is the total amount the buyers had in savings before they paid any deposit for the property?", - field_84: "Have any of the purchasers previously owned a property?", - field_85: "Was the previous property under shared ownership?", - field_86: "How long have the buyers been living in the property before the purchase? - Shared ownership", - field_87: "Is this a staircasing transaction?", - field_88: "What percentage of the property has been bought in this staircasing transaction?", - field_89: "What percentage of the property does the buyer now own in total?", - field_90: "Was this transaction part of a back-to-back staircasing transaction to facilitate sale of the home on the open market?", - - field_91: "Is this a resale?", - field_92: "What is the day of the exchange of contracts date?", - field_93: "What is the month of the exchange of contracts date?", - field_94: "What is the year of the exchange of contracts date?", - field_95: "What is the day of the practical completion or handover date?", - field_96: "What is the month of the practical completion or handover date?", - field_97: "What is the year of the practical completion or handover date?", - field_98: "Was the household re-housed under a local authority nominations agreement?", - field_99: "Was the buyer a private registered provider, housing association or local authority tenant immediately before this sale?", - field_100: "How many bedrooms did the buyer's previous property have?", - - field_101: "What was the type of the buyer's previous property?", - field_102: "What was the rent type of the buyer's previous property?", - field_103: "What was the full purchase price?", - field_104: "What was the initial percentage equity stake purchased?", - field_105: "Was a mortgage used for the purchase of this property? - Shared ownership", - field_106: "What is the mortgage amount?", - field_107: "What is the name of the mortgage lender? - Shared ownership", - field_108: "If 'other', what is the name of the mortgage lender?", - field_109: "What is the length of the mortgage in years? - Shared ownership", - field_110: "Does this include any extra borrowing?", - - field_111: "How much was the cash deposit paid on the property?", - field_112: "How much cash discount was given through Social Homebuy?", - field_113: "What is the basic monthly rent?", - field_114: "What are the total monthly leasehold charges for the property?", - field_115: "How long have the buyers been living in the property before the purchase? - Discounted ownership", - field_116: "What was the full purchase price?", - field_117: "What was the amount of any loan, grant, discount or subsidy given?", - field_118: "What was the percentage discount?", - field_119: "Was a mortgage used for the purchase of this property? - Discounted ownership", - field_120: "What is the mortgage amount?", - - field_121: "What is the name of the mortgage lender? - Discounted ownership", - field_122: "If 'other', what is the name of the mortgage lender?", - field_123: "What is the length of the mortgage in years? - Discounted ownership", - field_124: "Does this include any extra borrowing?", - field_125: "How much was the cash deposit paid on the property?", - field_126: "What are the total monthly leasehold charges for the property?", - field_127: "What is the full purchase price?", - field_128: "Was a mortgage used for the purchase of this property? - Outright sale", - field_129: "What is the mortgage amount?", - field_130: "What is the name of the mortgage lender? - Outright sale", - - field_131: "If 'other', what is the name of the mortgage lender?", - field_132: "What is the length of the mortgage in years? - Outright sale", - field_133: "Does this include any extra borrowing?", - field_134: "How much was the cash deposit paid on the property?", - field_135: "What are the total monthly leasehold charges for the property?", + field_42: "What is buyer 2 or person 2's working situation?", + field_43: "Will buyer 2 live in the property?", + field_44: "Besides the buyers, how many people will live in the property?", + field_45: "Relationship to buyer 1 for person 3", + field_46: "Age of person 3", + field_47: "Gender identity of person 3", + field_48: "Working situation of person 3", + field_49: "Relationship to buyer 1 for person 4", + + field_50: "Age of person 4", + field_51: "Gender identity of person 4", + field_52: "Working situation of person 4", + field_53: "Relationship to buyer 1 for person 5", + field_54: "Age of person 5", + field_55: "Gender identity of person 5", + field_56: "Working situation of person 5", + field_57: "Relationship to buyer 1 for person 6", + field_58: "Age of person 6", + field_59: "Gender identity of person 6", + + field_60: "Working situation of person 6", + field_61: "What was buyer 1's previous tenure?", + field_62: "Do you know the postcode of buyer 1's last settled home?", + field_63: "Part 1 of postcode of buyer 1's last settled home", + field_64: "Part 2 of postcode of buyer 1's last settled home", + field_65: "What is the local authority of buyer 1's last settled home?", + field_66: "Was the buyer registered with their PRP (HA)?", + field_67: "Was the buyer registered with another PRP (HA)?", + field_68: "Was the buyer registered with the local authority?", + field_69: "Was the buyer registered with a Help to Buy agent?", + + field_70: "At the time of purchase, was buyer 2 living at the same address as buyer 1?", + field_71: "What was buyer 2's previous tenure?", + field_72: "Has the buyer ever served in the UK Armed Forces and for how long?", + field_73: "Is the buyer still serving in the UK armed forces?", + field_74: "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_75: "Does anyone in the household consider themselves to have a disability?", + field_76: "Does anyone in the household use a wheelchair?", + field_77: "What is buyer 1's gross annual income?", + field_78: "Was buyer 1's income used for a mortgage application?", + field_79: "What is buyer 2's gross annual income?", + + field_80: "Was buyer 2's income used for a mortgage application?", + field_81: "Were the buyers receiving any of these housing-related benefits immediately before buying this property?", + field_82: "What is the total amount the buyers had in savings before they paid any deposit for the property?", + field_83: "Have any of the purchasers previously owned a property?", + field_84: "Was the previous property under shared ownership?", + field_85: "How long have the buyers been living in the property before the purchase? - Shared ownership", + field_86: "Is this a staircasing transaction?", + field_87: "What percentage of the property has been bought in this staircasing transaction?", + field_88: "What percentage of the property does the buyer now own in total?", + field_89: "Was this transaction part of a back-to-back staircasing transaction to facilitate sale of the home on the open market?", + + field_90: "Is this a resale?", + field_91: "What is the day of the exchange of contracts date?", + field_92: "What is the month of the exchange of contracts date?", + field_93: "What is the year of the exchange of contracts date?", + field_94: "What is the day of the practical completion or handover date?", + field_95: "What is the month of the practical completion or handover date?", + field_96: "What is the year of the practical completion or handover date?", + field_97: "Was the household re-housed under a local authority nominations agreement?", + field_98: "How many bedrooms did the buyer's previous property have?", + + field_99: "What was the type of the buyer's previous property?", + field_100: "What was the rent type of the buyer's previous property?", + field_101: "What was the full purchase price?", + field_102: "What was the initial percentage equity stake purchased?", + field_103: "Was a mortgage used for the purchase of this property? - Shared ownership", + field_104: "What is the mortgage amount?", + field_105: "What is the name of the mortgage lender? - Shared ownership", + field_106: "If 'other', what is the name of the mortgage lender?", + field_107: "What is the length of the mortgage in years? - Shared ownership", + field_108: "Does this include any extra borrowing?", + + field_109: "How much was the cash deposit paid on the property?", + field_110: "How much cash discount was given through Social Homebuy?", + field_111: "What is the basic monthly rent?", + field_112: "What are the total monthly leasehold charges for the property?", + field_113: "How long have the buyers been living in the property before the purchase? - Discounted ownership", + field_114: "What was the full purchase price?", + field_115: "What was the amount of any loan, grant, discount or subsidy given?", + field_116: "What was the percentage discount?", + field_117: "Was a mortgage used for the purchase of this property? - Discounted ownership", + field_118: "What is the mortgage amount?", + + field_119: "What is the name of the mortgage lender? - Discounted ownership", + field_120: "If 'other', what is the name of the mortgage lender?", + field_121: "What is the length of the mortgage in years? - Discounted ownership", + field_122: "Does this include any extra borrowing?", + field_123: "How much was the cash deposit paid on the property?", + field_124: "What are the total monthly leasehold charges for the property?", + field_125: "What is the full purchase price?", + field_126: "Was a mortgage used for the purchase of this property? - Outright sale", + field_127: "What is the mortgage amount?", + + field_128: "What is the length of the mortgage in years? - Outright sale", + field_129: "Does this include any extra borrowing?", + field_130: "How much was the cash deposit paid on the property?", + field_131: "What are the total monthly leasehold charges for the property?", }.freeze attribute :bulk_upload @@ -162,41 +157,41 @@ class BulkUpload::Sales::Year2024::RowParser attribute :field_1, :string attribute :field_2, :string - attribute :field_3, :integer + attribute :field_3, :string attribute :field_4, :integer attribute :field_5, :integer - attribute :field_6, :string - attribute :field_7, :integer + attribute :field_6, :integer + attribute :field_7, :string attribute :field_8, :integer attribute :field_9, :integer attribute :field_10, :integer + attribute :field_11, :integer - attribute :field_11, :string - attribute :field_12, :integer + attribute :field_12, :string attribute :field_13, :integer attribute :field_14, :integer attribute :field_15, :integer attribute :field_16, :integer attribute :field_17, :integer attribute :field_18, :integer - attribute :field_19, :string - attribute :field_20, :string - - attribute :field_21, :string + attribute :field_19, :integer + attribute :field_20, :integer + attribute :field_21, :integer attribute :field_22, :string attribute :field_23, :string + attribute :field_24, :string attribute :field_25, :string attribute :field_26, :string - attribute :field_27, :integer - attribute :field_28, :integer - attribute :field_29, :integer - attribute :field_30, :string - + attribute :field_27, :string + attribute :field_28, :string + attribute :field_29, :string + attribute :field_30, :integer attribute :field_31, :string - attribute :field_32, :integer + + attribute :field_32, :string attribute :field_33, :integer - attribute :field_34, :string + attribute :field_34, :integer attribute :field_35, :integer attribute :field_36, :integer attribute :field_37, :string @@ -205,40 +200,40 @@ class BulkUpload::Sales::Year2024::RowParser attribute :field_40, :integer attribute :field_41, :integer - attribute :field_42, :string + attribute :field_42, :integer attribute :field_43, :integer attribute :field_44, :integer - attribute :field_45, :integer + attribute :field_45, :string attribute :field_46, :string attribute :field_47, :string - attribute :field_48, :string - attribute :field_49, :integer - attribute :field_50, :string + attribute :field_48, :integer + attribute :field_49, :string + attribute :field_50, :string attribute :field_51, :string - attribute :field_52, :string - attribute :field_53, :integer + attribute :field_52, :integer + attribute :field_53, :string 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, :string attribute :field_59, :string - attribute :field_60, :string + attribute :field_60, :integer attribute :field_61, :integer attribute :field_62, :integer - attribute :field_63, :integer + attribute :field_63, :string attribute :field_64, :string attribute :field_65, :string - attribute :field_66, :string + attribute :field_66, :integer attribute :field_67, :integer attribute :field_68, :integer attribute :field_69, :integer - attribute :field_70, :integer - attribute :field_71, :integer - attribute :field_72, :string + attribute :field_70, :integer + attribute :field_71, :string + attribute :field_72, :integer attribute :field_73, :integer attribute :field_74, :integer attribute :field_75, :integer @@ -246,8 +241,8 @@ class BulkUpload::Sales::Year2024::RowParser attribute :field_77, :integer attribute :field_78, :integer attribute :field_79, :integer - attribute :field_80, :integer + attribute :field_80, :integer attribute :field_81, :integer attribute :field_82, :integer attribute :field_83, :integer @@ -257,8 +252,8 @@ class BulkUpload::Sales::Year2024::RowParser attribute :field_87, :integer attribute :field_88, :integer attribute :field_89, :integer - attribute :field_90, :integer + attribute :field_90, :integer attribute :field_91, :integer attribute :field_92, :integer attribute :field_93, :integer @@ -267,62 +262,58 @@ class BulkUpload::Sales::Year2024::RowParser attribute :field_96, :integer attribute :field_97, :integer attribute :field_98, :integer + attribute :field_99, :integer attribute :field_100, :integer - 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_106, :string attribute :field_107, :integer - attribute :field_108, :string + attribute :field_108, :integer + attribute :field_109, :integer attribute :field_110, :integer - - attribute :field_111, :integer - attribute :field_112, :integer - attribute :field_113, :decimal - attribute :field_114, :decimal + attribute :field_111, :decimal + attribute :field_112, :decimal + attribute :field_113, :integer + attribute :field_114, :integer attribute :field_115, :integer attribute :field_116, :integer attribute :field_117, :integer attribute :field_118, :integer - attribute :field_119, :integer - attribute :field_120, :integer + attribute :field_119, :integer + attribute :field_120, :string attribute :field_121, :integer - attribute :field_122, :string + attribute :field_122, :integer attribute :field_123, :integer attribute :field_124, :integer attribute :field_125, :integer attribute :field_126, :integer attribute :field_127, :integer + attribute :field_128, :integer attribute :field_129, :integer attribute :field_130, :integer + attribute :field_131, :integer - attribute :field_131, :string - attribute :field_132, :integer - attribute :field_133, :integer - attribute :field_134, :integer - attribute :field_135, :integer - - validates :field_3, + validates :field_4, presence: { message: I18n.t("validations.not_answered", question: "sale completion date (day)"), category: :setup, }, on: :after_log - validates :field_4, + validates :field_5, presence: { message: I18n.t("validations.not_answered", question: "sale completion date (month)"), category: :setup, }, on: :after_log - validates :field_5, + validates :field_6, presence: { message: I18n.t("validations.not_answered", question: "sale completion date (year)"), category: :setup, @@ -331,26 +322,26 @@ class BulkUpload::Sales::Year2024::RowParser with: /\A\d{2}\z/, message: I18n.t("validations.setup.saledate.year_not_two_digits"), category: :setup, - if: proc { field_5.present? }, + if: proc { field_6.present? }, }, on: :after_log - validates :field_7, + validates :field_8, presence: { message: I18n.t("validations.not_answered", question: "purchase made under ownership scheme"), category: :setup, }, on: :after_log - validates :field_8, + validates :field_9, inclusion: { in: [2, 30, 18, 16, 24, 28, 31, 32], - if: proc { field_8.present? }, + if: proc { field_9.present? }, category: :setup, - question: QUESTIONS[:field_8].downcase, + question: QUESTIONS[:field_9].downcase, }, on: :before_log - validates :field_8, + validates :field_9, presence: { message: I18n.t("validations.not_answered", question: "type of shared ownership sale"), category: :setup, @@ -358,16 +349,16 @@ class BulkUpload::Sales::Year2024::RowParser }, on: :after_log - validates :field_9, + validates :field_10, inclusion: { in: [8, 14, 27, 9, 29, 21, 22], - if: proc { field_9.present? }, + if: proc { field_10.present? }, category: :setup, - question: QUESTIONS[:field_9].downcase, + question: QUESTIONS[:field_10].downcase, }, on: :before_log - validates :field_9, + validates :field_10, presence: { message: I18n.t("validations.not_answered", question: "type of discounted ownership sale"), category: :setup, @@ -375,16 +366,16 @@ class BulkUpload::Sales::Year2024::RowParser }, on: :after_log - validates :field_10, + validates :field_11, inclusion: { in: [10, 12], - if: proc { field_10.present? }, + if: proc { field_11.present? }, category: :setup, - question: QUESTIONS[:field_10].downcase, + question: QUESTIONS[:field_11].downcase, }, on: :before_log - validates :field_10, + validates :field_11, presence: { message: I18n.t("validations.not_answered", question: "type of outright sale"), category: :setup, @@ -392,24 +383,24 @@ class BulkUpload::Sales::Year2024::RowParser }, on: :after_log - validates :field_11, + validates :field_12, presence: { message: I18n.t("validations.not_answered", question: "type of outright sale"), category: :setup, - if: proc { field_10 == 12 }, + if: proc { field_11 == 12 }, }, on: :after_log - validates :field_12, + validates :field_13, inclusion: { in: [1, 2], - if: proc { outright_sale? && field_12.present? }, + if: proc { outright_sale? && field_13.present? }, category: :setup, - question: QUESTIONS[:field_12].downcase, + question: QUESTIONS[:field_13].downcase, }, on: :before_log - validates :field_12, + validates :field_13, presence: { message: I18n.t("validations.not_answered", question: "company buyer"), category: :setup, @@ -417,16 +408,16 @@ class BulkUpload::Sales::Year2024::RowParser }, on: :after_log - validates :field_13, + validates :field_14, inclusion: { in: [1, 2], - if: proc { outright_sale? && field_13.present? }, + if: proc { outright_sale? && field_14.present? }, category: :setup, - question: QUESTIONS[:field_13].downcase, + question: QUESTIONS[:field_14].downcase, }, on: :before_log - validates :field_13, + validates :field_14, presence: { message: I18n.t("validations.not_answered", question: "buyers living in property"), category: :setup, @@ -434,7 +425,7 @@ class BulkUpload::Sales::Year2024::RowParser }, on: :after_log - validates :field_14, + validates :field_15, presence: { message: I18n.t("validations.not_answered", question: "joint purchase"), category: :setup, @@ -442,7 +433,7 @@ class BulkUpload::Sales::Year2024::RowParser }, on: :after_log - validates :field_15, + validates :field_16, presence: { message: I18n.t("validations.not_answered", question: "more than 2 joint buyers"), category: :setup, @@ -540,20 +531,20 @@ class BulkUpload::Sales::Year2024::RowParser end def purchaser_code - field_6 + field_7 end def spreadsheet_duplicate_hash attributes.slice( "field_1", # owning org - "field_3", # saledate "field_4", # saledate "field_5", # saledate - "field_6", # purchaser_code - "field_24", # postcode - "field_25", # postcode - "field_30", # age1 - "field_31", # sex1 + "field_6", # saledate + "field_7", # purchaser_code + "field_27", # postcode + "field_28", # postcode + "field_31", # age1 + "field_32", # sex1 "field_35", # ecstat1 ) end @@ -567,13 +558,13 @@ class BulkUpload::Sales::Year2024::RowParser private def validate_data_protection_answered - unless field_29 == 1 - errors.add(:field_29, I18n.t("validations.not_answered", question: QUESTIONS[:field_29].downcase), category: :setup) + unless field_18 == 1 + errors.add(:field_18, I18n.t("validations.not_answered", question: QUESTIONS[:field_18].downcase), category: :setup) end end def validate_buyers_organisations - organisations_fields = %i[field_67 field_68 field_69 field_70] + organisations_fields = %i[field_66 field_67 field_68 field_69] if organisations_fields.all? { |field| attributes[field.to_s].blank? } organisations_fields.each do |field| errors.add(field, "At least one option must be selected of these four") @@ -582,11 +573,11 @@ private end def prevtenbuy2 - case field_72 + case field_71 when "R" 0 else - field_72 + field_71 end end @@ -608,182 +599,182 @@ private end def validate_uprn_exists_if_any_key_address_fields_are_blank - if field_19.blank? && (field_20.blank? || field_22.blank?) - errors.add(:field_19, I18n.t("validations.not_answered", question: "UPRN")) + if field_22.blank? && (field_23.blank? || field_25.blank?) + errors.add(:field_22, I18n.t("validations.not_answered", question: "UPRN")) end end def validate_address_fields - if field_19.blank? || log.errors.attribute_names.include?(:uprn) - if field_20.blank? - errors.add(:field_20, I18n.t("validations.not_answered", question: "address line 1")) + if field_22.blank? || log.errors.attribute_names.include?(:uprn) + if field_23.blank? + errors.add(:field_23, I18n.t("validations.not_answered", question: "address line 1")) end - if field_22.blank? - errors.add(:field_22, I18n.t("validations.not_answered", question: "town or city")) + if field_25.blank? + errors.add(:field_25, I18n.t("validations.not_answered", question: "town or city")) end end end def shared_ownership? - field_7 == 1 + field_8 == 1 end def discounted_ownership? - field_7 == 2 + field_8 == 2 end def outright_sale? - field_7 == 3 + field_8 == 3 end def joint_purchase? - field_116 == 1 + field_114 == 1 end def joint_purchase_asked? - shared_ownership? || discounted_ownership? || field_114 == 2 + shared_ownership? || discounted_ownership? || field_112 == 2 end def field_mapping_for_errors { - purchid: %i[field_6], - saledate: %i[field_3 field_4 field_5], - noint: %i[field_28], - age1_known: %i[field_30], - age1: %i[field_30], + purchid: %i[field_7], + saledate: %i[field_4 field_5 field_6], + noint: %i[field_17], + age1_known: %i[field_31], + age1: %i[field_31], age2_known: %i[field_38], age2: %i[field_38], - age3_known: %i[field_47], - age3: %i[field_47], - age4_known: %i[field_51], - age4: %i[field_51], - age5_known: %i[field_55], - age5: %i[field_55], - age6_known: %i[field_59], - age6: %i[field_59], - sex1: %i[field_31], + age3_known: %i[field_46], + age3: %i[field_46], + age4_known: %i[field_50], + age4: %i[field_50], + age5_known: %i[field_54], + age5: %i[field_54], + age6_known: %i[field_58], + age6: %i[field_58], + sex1: %i[field_32], sex2: %i[field_39], - sex3: %i[field_48], + sex3: %i[field_47], - sex4: %i[field_52], - sex5: %i[field_56], - sex6: %i[field_60], + sex4: %i[field_51], + sex5: %i[field_55], + sex6: %i[field_59], relat2: %i[field_37], - relat3: %i[field_46], - relat4: %i[field_50], - relat5: %i[field_54], - relat6: %i[field_58], + relat3: %i[field_45], + relat4: %i[field_49], + relat5: %i[field_53], + relat6: %i[field_57], ecstat1: %i[field_35], - ecstat2: %i[field_43], - ecstat3: %i[field_49], - - ecstat4: %i[field_53], - ecstat5: %i[field_57], - ecstat6: %i[field_61], - ethnic_group: %i[field_32], - ethnic: %i[field_32], - national: %i[field_33], - income1nk: %i[field_78], - income1: %i[field_78], - income2nk: %i[field_80], - income2: %i[field_80], - inc1mort: %i[field_79], - inc2mort: %i[field_81], - savingsnk: %i[field_83], - savings: %i[field_83], - prevown: %i[field_84], - prevten: %i[field_62], - prevloc: %i[field_66], - previous_la_known: %i[field_66], - ppcodenk: %i[field_63], - ppostcode_full: %i[field_64 field_65], - pregyrha: %i[field_67], - pregla: %i[field_69], - pregghb: %i[field_70], - pregother: %i[field_68], - disabled: %i[field_76], - - wheel: %i[field_77], - beds: %i[field_16], - proptype: %i[field_17], - builtype: %i[field_18], - la_known: %i[field_26], - la: %i[field_26], - - is_la_inferred: %i[field_26], - pcodenk: %i[field_24 field_25], - postcode_full: %i[field_24 field_25], - wchair: %i[field_27], - - type: %i[field_8 field_9 field_10 field_7], - resale: %i[field_91], - hodate: %i[field_95 field_96 field_97], - exdate: %i[field_92 field_93 field_94], - - lanomagr: %i[field_98], - frombeds: %i[field_100], - fromprop: %i[field_101], - value: %i[field_103 field_116 field_127], - equity: %i[field_104], - mortgage: %i[field_106 field_120 field_129], - extrabor: %i[field_110 field_124 field_133], - deposit: %i[field_111 field_125 field_134], - cashdis: %i[field_112], - mrent: %i[field_113], - - has_mscharge: %i[field_114 field_126 field_135], - mscharge: %i[field_114 field_126 field_135], - grant: %i[field_117], - discount: %i[field_118], - othtype: %i[field_11], + ecstat2: %i[field_42], + ecstat3: %i[field_48], + + ecstat4: %i[field_52], + ecstat5: %i[field_56], + ecstat6: %i[field_60], + ethnic_group: %i[field_33], + ethnic: %i[field_33], + national: %i[field_34], + income1nk: %i[field_77], + income1: %i[field_77], + income2nk: %i[field_79], + income2: %i[field_79], + inc1mort: %i[field_78], + inc2mort: %i[field_80], + savingsnk: %i[field_82], + savings: %i[field_82], + prevown: %i[field_83], + prevten: %i[field_61], + prevloc: %i[field_65], + previous_la_known: %i[field_65], + ppcodenk: %i[field_62], + ppostcode_full: %i[field_63 field_64], + pregyrha: %i[field_66], + pregla: %i[field_68], + pregghb: %i[field_69], + pregother: %i[field_67], + disabled: %i[field_75], + + wheel: %i[field_76], + beds: %i[field_19], + proptype: %i[field_20], + builtype: %i[field_21], + la_known: %i[field_29], + la: %i[field_29], + + is_la_inferred: %i[field_29], + pcodenk: %i[field_27 field_28], + postcode_full: %i[field_27 field_28], + wchair: %i[field_30], + + type: %i[field_9 field_10 field_11 field_8], + resale: %i[field_90], + hodate: %i[field_94 field_95 field_96], + exdate: %i[field_91 field_92 field_93], + + lanomagr: %i[field_97], + frombeds: %i[field_98], + fromprop: %i[field_99], + soctenant: %i[field_98 field_99 field_100], + value: %i[field_101 field_114 field_125], + equity: %i[field_102], + mortgage: %i[field_104 field_118 field_127], + extrabor: %i[field_108 field_122 field_129], + deposit: %i[field_109 field_123 field_130], + cashdis: %i[field_110], + mrent: %i[field_111], + + has_mscharge: %i[field_112 field_124 field_131], + mscharge: %i[field_112 field_124 field_131], + grant: %i[field_115], + discount: %i[field_116], + othtype: %i[field_12], owning_organisation_id: %i[field_1], - created_by: %i[field_2], - hhregres: %i[field_73], - hhregresstill: %i[field_74], - armedforcesspouse: %i[field_75], - - mortgagelender: %i[field_107 field_121 field_130], - mortgagelenderother: %i[field_108 field_122 field_131], - - hb: %i[field_82], - mortlen: %i[field_109 field_123 field_132], - proplen: %i[field_115 field_86], - - jointmore: %i[field_15], - staircase: %i[field_87], - privacynotice: %i[field_29], - ownershipsch: %i[field_7], - companybuy: %i[field_12], - buylivein: %i[field_13], - - jointpur: %i[field_14], + created_by: %i[field_3], + hhregres: %i[field_72], + hhregresstill: %i[field_73], + armedforcesspouse: %i[field_74], + + mortgagelender: %i[field_105 field_119], + mortgagelenderother: %i[field_106 field_120], + + hb: %i[field_81], + mortlen: %i[field_107 field_121 field_128], + proplen: %i[field_113 field_85], + + jointmore: %i[field_16], + staircase: %i[field_86], + privacynotice: %i[field_18], + ownershipsch: %i[field_8], + companybuy: %i[field_13], + buylivein: %i[field_14], + + jointpur: %i[field_15], buy1livein: %i[field_36], - buy2livein: %i[field_44], - hholdcount: %i[field_45], - stairbought: %i[field_88], - stairowned: %i[field_89], - socprevten: %i[field_102], - mortgageused: %i[field_105 field_119 field_128], - soctenant: %i[field_99], - - uprn: %i[field_19], - address_line1: %i[field_20], - address_line2: %i[field_21], - town_or_city: %i[field_22], - county: %i[field_23], + buy2livein: %i[field_43], + hholdcount: %i[field_44], + stairbought: %i[field_87], + stairowned: %i[field_88], + socprevten: %i[field_100], + mortgageused: %i[field_103 field_117 field_126], + + uprn: %i[field_22], + address_line1: %i[field_23], + address_line2: %i[field_24], + town_or_city: %i[field_25], + county: %i[field_26], ethnic_group2: %i[field_40], ethnicbuy2: %i[field_40], nationalbuy2: %i[field_41], - buy2living: %i[field_71], - prevtenbuy2: %i[field_72], + buy2living: %i[field_70], + prevtenbuy2: %i[field_71], - prevshared: %i[field_85], + prevshared: %i[field_84], - staircasesale: %i[field_90], + staircasesale: %i[field_89], } end @@ -792,45 +783,45 @@ private attributes["purchid"] = purchaser_code attributes["saledate"] = saledate - attributes["noint"] = 2 if field_28 == 1 + attributes["noint"] = 2 if field_17 == 1 attributes["age1_known"] = age1_known? - attributes["age1"] = field_30 if attributes["age1_known"]&.zero? && field_30&.match(/\A\d{1,3}\z|\AR\z/) + attributes["age1"] = field_31 if attributes["age1_known"]&.zero? && field_31&.match(/\A\d{1,3}\z|\AR\z/) attributes["age2_known"] = age2_known? 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_47 if attributes["age3_known"]&.zero? && field_47&.match(/\A\d{1,3}\z|\AR\z/) + attributes["age3"] = field_46 if attributes["age3_known"]&.zero? && field_46&.match(/\A\d{1,3}\z|\AR\z/) attributes["age4_known"] = age4_known? - attributes["age4"] = field_51 if attributes["age4_known"]&.zero? && field_51&.match(/\A\d{1,3}\z|\AR\z/) + attributes["age4"] = field_50 if attributes["age4_known"]&.zero? && field_50&.match(/\A\d{1,3}\z|\AR\z/) attributes["age5_known"] = age5_known? - attributes["age5"] = field_55 if attributes["age5_known"]&.zero? && field_55&.match(/\A\d{1,3}\z|\AR\z/) + attributes["age5"] = field_54 if attributes["age5_known"]&.zero? && field_54&.match(/\A\d{1,3}\z|\AR\z/) attributes["age6_known"] = age6_known? - attributes["age6"] = field_59 if attributes["age6_known"]&.zero? && field_59&.match(/\A\d{1,3}\z|\AR\z/) + attributes["age6"] = field_58 if attributes["age6_known"]&.zero? && field_58&.match(/\A\d{1,3}\z|\AR\z/) - attributes["sex1"] = field_31 + attributes["sex1"] = field_32 attributes["sex2"] = field_39 - attributes["sex3"] = field_48 - attributes["sex4"] = field_52 - attributes["sex5"] = field_56 - attributes["sex6"] = field_60 + attributes["sex3"] = field_47 + attributes["sex4"] = field_51 + attributes["sex5"] = field_55 + attributes["sex6"] = field_59 attributes["relat2"] = field_37 - attributes["relat3"] = field_46 - attributes["relat4"] = field_50 - attributes["relat5"] = field_54 - attributes["relat6"] = field_58 + attributes["relat3"] = field_45 + attributes["relat4"] = field_49 + attributes["relat5"] = field_53 + attributes["relat6"] = field_57 attributes["ecstat1"] = field_35 - attributes["ecstat2"] = field_43 - attributes["ecstat3"] = field_49 - attributes["ecstat4"] = field_53 - attributes["ecstat5"] = field_57 - attributes["ecstat6"] = field_61 + attributes["ecstat2"] = field_42 + attributes["ecstat3"] = field_48 + attributes["ecstat4"] = field_52 + attributes["ecstat5"] = field_56 + attributes["ecstat6"] = field_60 attributes["details_known_2"] = details_known?(2) attributes["details_known_3"] = details_known?(3) @@ -839,157 +830,156 @@ private attributes["details_known_6"] = details_known?(6) attributes["ethnic_group"] = ethnic_group_from_ethnic - attributes["ethnic"] = field_32 - attributes["national"] = field_33 + attributes["ethnic"] = field_33 + attributes["national"] = field_34 - attributes["income1nk"] = field_78.present? ? 0 : 1 - attributes["income1"] = field_78 + attributes["income1nk"] = field_77.present? ? 0 : 1 + attributes["income1"] = field_77 - attributes["income2nk"] = field_80.present? ? 0 : 1 - attributes["income2"] = field_80 + attributes["income2nk"] = field_79.present? ? 0 : 1 + attributes["income2"] = field_79 - attributes["inc1mort"] = field_79 - attributes["inc2mort"] = field_81 + attributes["inc1mort"] = field_78 + attributes["inc2mort"] = field_80 - attributes["savingsnk"] = field_83.present? ? 0 : 1 - attributes["savings"] = field_83 - attributes["prevown"] = field_84 + attributes["savingsnk"] = field_82.present? ? 0 : 1 + attributes["savings"] = field_82 + attributes["prevown"] = field_83 - attributes["prevten"] = field_62 - attributes["prevloc"] = field_66 + attributes["prevten"] = field_61 + attributes["prevloc"] = field_65 attributes["previous_la_known"] = previous_la_known attributes["ppcodenk"] = previous_postcode_known attributes["ppostcode_full"] = ppostcode_full - attributes["pregyrha"] = field_67 - attributes["pregla"] = field_69 - attributes["pregghb"] = field_70 - attributes["pregother"] = field_68 - - attributes["disabled"] = field_76 - attributes["wheel"] = field_77 - attributes["beds"] = field_16 - attributes["proptype"] = field_17 - attributes["builtype"] = field_18 - attributes["la_known"] = field_26.present? ? 1 : 0 - attributes["la"] = field_26 + attributes["pregyrha"] = field_66 + attributes["pregla"] = field_68 + attributes["pregghb"] = field_69 + attributes["pregother"] = field_67 + + attributes["disabled"] = field_75 + attributes["wheel"] = field_76 + attributes["beds"] = field_19 + attributes["proptype"] = field_20 + attributes["builtype"] = field_21 + attributes["la_known"] = field_29.present? ? 1 : 0 + attributes["la"] = field_29 attributes["is_la_inferred"] = false attributes["pcodenk"] = 0 if postcode_full.present? attributes["postcode_full"] = postcode_full - attributes["wchair"] = field_27 + attributes["wchair"] = field_30 attributes["type"] = sale_type - attributes["resale"] = field_91 + attributes["resale"] = field_90 attributes["hodate"] = hodate attributes["exdate"] = exdate - attributes["lanomagr"] = field_98 + attributes["lanomagr"] = field_97 - attributes["frombeds"] = field_100 - attributes["fromprop"] = field_101 + attributes["frombeds"] = field_98 + attributes["fromprop"] = field_99 attributes["value"] = value - attributes["equity"] = field_104 + attributes["equity"] = field_102 attributes["mortgage"] = mortgage attributes["extrabor"] = extrabor attributes["deposit"] = deposit - attributes["cashdis"] = field_112 - attributes["mrent"] = field_113 + attributes["cashdis"] = field_110 + attributes["mrent"] = field_111 attributes["mscharge"] = mscharge if mscharge&.positive? attributes["has_mscharge"] = attributes["mscharge"].present? ? 1 : 0 - attributes["grant"] = field_117 - attributes["discount"] = field_118 + attributes["grant"] = field_115 + attributes["discount"] = field_116 - attributes["othtype"] = field_11 + attributes["othtype"] = field_12 attributes["owning_organisation"] = owning_organisation attributes["managing_organisation"] = managing_organisation attributes["created_by"] = created_by || bulk_upload.user - attributes["hhregres"] = field_73 - attributes["hhregresstill"] = field_74 - attributes["armedforcesspouse"] = field_75 + attributes["hhregres"] = field_72 + attributes["hhregresstill"] = field_73 + attributes["armedforcesspouse"] = field_74 attributes["mortgagelender"] = mortgagelender attributes["mortgagelenderother"] = mortgagelenderother - attributes["hb"] = field_82 + attributes["hb"] = field_81 attributes["mortlen"] = mortlen attributes["proplen"] = proplen if proplen&.positive? attributes["proplen_asked"] = attributes["proplen"]&.present? ? 0 : 1 - attributes["jointmore"] = field_15 - attributes["staircase"] = field_87 - attributes["privacynotice"] = field_29 - attributes["ownershipsch"] = field_7 - attributes["companybuy"] = field_12 - attributes["buylivein"] = field_13 - attributes["jointpur"] = field_14 + attributes["jointmore"] = field_16 + attributes["staircase"] = field_86 + attributes["privacynotice"] = field_18 + attributes["ownershipsch"] = field_8 + attributes["companybuy"] = field_13 + attributes["buylivein"] = field_14 + attributes["jointpur"] = field_15 attributes["buy1livein"] = field_36 - attributes["buy2livein"] = field_44 - attributes["hholdcount"] = field_45 - attributes["stairbought"] = field_88 - attributes["stairowned"] = field_89 - attributes["socprevten"] = field_102 + attributes["buy2livein"] = field_43 + attributes["hholdcount"] = field_44 + attributes["stairbought"] = field_87 + attributes["stairowned"] = field_88 + attributes["socprevten"] = field_100 + attributes["soctenant"] = [attributes["socprevten"], attributes["frombeds"], attributes["fromprop"]].any?(&:present?) ? 1 : 0 attributes["mortgageused"] = mortgageused - attributes["uprn"] = field_19 - attributes["uprn_known"] = field_19.present? ? 1 : 0 - attributes["uprn_confirmed"] = 1 if field_19.present? + attributes["uprn"] = field_22 + attributes["uprn_known"] = field_22.present? ? 1 : 0 + attributes["uprn_confirmed"] = 1 if field_22.present? attributes["skip_update_uprn_confirmed"] = true - attributes["address_line1"] = field_20 - attributes["address_line2"] = field_21 - attributes["town_or_city"] = field_22 - attributes["county"] = field_23 + attributes["address_line1"] = field_23 + attributes["address_line2"] = field_24 + attributes["town_or_city"] = field_25 + attributes["county"] = field_26 attributes["ethnic_group2"] = infer_buyer2_ethnic_group_from_ethnic attributes["ethnicbuy2"] = field_40 attributes["nationalbuy2"] = field_41 - attributes["buy2living"] = field_71 + attributes["buy2living"] = field_70 attributes["prevtenbuy2"] = prevtenbuy2 - attributes["prevshared"] = field_85 - - attributes["staircasesale"] = field_90 + attributes["prevshared"] = field_84 - attributes["soctenant"] = field_99 + attributes["staircasesale"] = field_89 attributes end def saledate - Date.new(field_5 + 2000, field_4, field_3) if field_5.present? && field_4.present? && field_3.present? + Date.new(field_6 + 2000, field_5, field_4) if field_6.present? && field_5.present? && field_4.present? rescue Date::Error Date.new end def hodate - Date.new(field_97 + 2000, field_96, field_95) if field_97.present? && field_96.present? && field_95.present? + Date.new(field_96 + 2000, field_95, field_94) if field_96.present? && field_95.present? && field_94.present? rescue Date::Error Date.new end def exdate - Date.new(field_94 + 2000, field_93, field_92) if field_94.present? && field_93.present? && field_92.present? + Date.new(field_93 + 2000, field_92, field_91) if field_93.present? && field_92.present? && field_91.present? rescue Date::Error Date.new end def age1_known? - return 1 if field_30 == "R" + return 1 if field_31 == "R" 0 end [ { person: 2, field: :field_38 }, - { person: 3, field: :field_47 }, - { person: 4, field: :field_51 }, - { person: 5, field: :field_55 }, - { person: 6, field: :field_59 }, + { person: 3, field: :field_46 }, + { person: 4, field: :field_50 }, + { person: 5, field: :field_54 }, + { person: 6, field: :field_58 }, ].each do |hash| define_method("age#{hash[:person]}_known?") do return 1 if public_send(hash[:field]) == "R" @@ -1002,19 +992,19 @@ private end def person_3_present? - field_47.present? || field_48.present? || field_46.present? + field_46.present? || field_47.present? || field_45.present? end def person_4_present? - field_51.present? || field_52.present? || field_50.present? + field_50.present? || field_51.present? || field_49.present? end def person_5_present? - field_55.present? || field_56.present? || field_54.present? + field_54.present? || field_55.present? || field_53.present? end def person_6_present? - field_59.present? || field_60.present? || field_58.present? + field_58.present? || field_59.present? || field_57.present? end def details_known?(person_n) @@ -1022,9 +1012,9 @@ private end def ethnic_group_from_ethnic - return nil if field_32.blank? + return nil if field_33.blank? - case field_32 + case field_33 when 1, 2, 3, 18 0 when 4, 5, 6, 7 @@ -1041,76 +1031,74 @@ private end def postcode_full - "#{field_24} #{field_25}" if field_24 && field_25 + "#{field_27} #{field_28}" if field_27 && field_28 end def ppostcode_full - "#{field_64} #{field_65}" if field_64 && field_65 + "#{field_63} #{field_64}" if field_63 && field_64 end def sale_type - return field_8 if shared_ownership? - return field_9 if discounted_ownership? - return field_10 if outright_sale? + return field_9 if shared_ownership? + return field_10 if discounted_ownership? + return field_11 if outright_sale? end def value - return field_103 if shared_ownership? - return field_116 if discounted_ownership? - return field_127 if outright_sale? + return field_101 if shared_ownership? + return field_114 if discounted_ownership? + return field_125 if outright_sale? end def mortgage - return field_106 if shared_ownership? - return field_120 if discounted_ownership? - return field_129 if outright_sale? + return field_104 if shared_ownership? + return field_118 if discounted_ownership? + return field_127 if outright_sale? end def extrabor - return field_110 if shared_ownership? - return field_124 if discounted_ownership? - return field_133 if outright_sale? + return field_108 if shared_ownership? + return field_122 if discounted_ownership? + return field_129 if outright_sale? end def deposit - return field_111 if shared_ownership? - return field_125 if discounted_ownership? - return field_134 if outright_sale? + return field_109 if shared_ownership? + return field_123 if discounted_ownership? + return field_130 if outright_sale? end def mscharge - return field_114 if shared_ownership? - return field_126 if discounted_ownership? - return field_135 if outright_sale? + return field_112 if shared_ownership? + return field_124 if discounted_ownership? + return field_131 if outright_sale? end def mortgagelender - return field_107 if shared_ownership? - return field_121 if discounted_ownership? - return field_130 if outright_sale? + return field_105 if shared_ownership? + return field_119 if discounted_ownership? end def mortgagelenderother - return field_108 if shared_ownership? - return field_122 if discounted_ownership? - return field_131 if outright_sale? + return field_106 if shared_ownership? + return field_120 if discounted_ownership? end def mortlen - return field_109 if shared_ownership? - return field_123 if discounted_ownership? - return field_132 if outright_sale? + return field_107 if shared_ownership? + return field_121 if discounted_ownership? + return field_128 if outright_sale? end def proplen - return field_86 if shared_ownership? - return field_115 if discounted_ownership? + return field_85 if shared_ownership? + return field_113 if discounted_ownership? end def mortgageused - return field_105 if shared_ownership? - return field_119 if discounted_ownership? - return field_128 if outright_sale? + return field_103 if shared_ownership? + return field_117 if discounted_ownership? + return field_126 if outright_sale? end def owning_organisation @@ -1118,17 +1106,17 @@ private end def created_by - @created_by ||= User.where("lower(email) = ?", field_2&.downcase).first + @created_by ||= User.where("lower(email) = ?", field_3&.downcase).first end def previous_la_known - field_66.present? ? 1 : 0 + field_65.present? ? 1 : 0 end def previous_postcode_known - return 1 if field_63 == 2 + return 1 if field_62 == 2 - 0 if field_63 == 1 + 0 if field_62 == 1 end def block_log_creation! @@ -1192,10 +1180,10 @@ private end def validate_created_by_exists - return if field_2.blank? + return if field_3.blank? unless created_by - errors.add(:field_2, "User with the specified email could not be found") + errors.add(:field_3, "User with the specified email could not be found") end end @@ -1205,7 +1193,7 @@ private return if created_by.organisation == owning_organisation&.absorbing_organisation || created_by.organisation == managing_organisation&.absorbing_organisation block_log_creation! - errors.add(:field_2, "User must be related to owning organisation or managing organisation", category: :setup) + errors.add(:field_3, "User must be related to owning organisation or managing organisation", category: :setup) end def managing_organisation @@ -1218,8 +1206,8 @@ private if owning_organisation && managing_organisation && !owning_organisation.can_be_managed_by?(organisation: managing_organisation) block_log_creation! - if errors[:field_2].blank? - errors.add(:field_2, "This user belongs to an organisation that does not have a relationship with the owning organisation", category: :setup) + if errors[:field_3].blank? + errors.add(:field_3, "This user belongs to an organisation that does not have a relationship with the owning organisation", category: :setup) end end end @@ -1283,12 +1271,12 @@ private def validate_relevant_collection_window return if saledate.blank? || bulk_upload.form.blank? - return if errors.key?(:field_3) || errors.key?(:field_4) || errors.key?(:field_5) + return if errors.key?(:field_4) || errors.key?(:field_5) || errors.key?(:field_6) unless bulk_upload.form.valid_start_date_for_form?(saledate) - errors.add(:field_3, I18n.t("validations.date.outside_collection_window", year_combo: bulk_upload.year_combo, start_year: bulk_upload.year, end_year: bulk_upload.end_year), category: :setup) errors.add(:field_4, I18n.t("validations.date.outside_collection_window", year_combo: bulk_upload.year_combo, start_year: bulk_upload.year, end_year: bulk_upload.end_year), category: :setup) errors.add(:field_5, I18n.t("validations.date.outside_collection_window", year_combo: bulk_upload.year_combo, start_year: bulk_upload.year, end_year: bulk_upload.end_year), category: :setup) + errors.add(:field_6, I18n.t("validations.date.outside_collection_window", year_combo: bulk_upload.year_combo, start_year: bulk_upload.year, end_year: bulk_upload.end_year), category: :setup) end end @@ -1297,15 +1285,15 @@ private error_message = "This is a duplicate log" errors.add(:field_1, error_message) # Owning org - errors.add(:field_3, error_message) # Sale completion date errors.add(:field_4, error_message) # Sale completion date errors.add(:field_5, error_message) # Sale completion date - errors.add(:field_24, error_message) # Postcode - errors.add(:field_25, error_message) # Postcode - errors.add(:field_30, error_message) # Buyer 1 age - errors.add(:field_31, error_message) # Buyer 1 gender + errors.add(:field_6, error_message) # Sale completion date + errors.add(:field_27, error_message) # Postcode + errors.add(:field_28, error_message) # Postcode + errors.add(:field_31, error_message) # Buyer 1 age + errors.add(:field_32, error_message) # Buyer 1 gender errors.add(:field_35, error_message) # Buyer 1 working situation - errors.add(:field_6, error_message) # Purchaser code + errors.add(:field_7, error_message) # Purchaser code end end diff --git a/config/locales/en.yml b/config/locales/en.yml index 862528021..8838c6a80 100644 --- a/config/locales/en.yml +++ b/config/locales/en.yml @@ -44,11 +44,11 @@ en: bulk_upload/row_parser: &bulk_upload__row_parser__base inclusion: Enter a valid value for %{question} spreadsheet_dupe: This is a duplicate of a log in your file - bulk_upload/lettings/year2022/row_parser: + bulk_upload/lettings/year2024/row_parser: <<: *bulk_upload__row_parser__base bulk_upload/lettings/year2023/row_parser: <<: *bulk_upload__row_parser__base - bulk_upload/sales/year2022/row_parser: + bulk_upload/sales/year2024/row_parser: <<: *bulk_upload__row_parser__base bulk_upload/sales/year2023/row_parser: <<: *bulk_upload__row_parser__base diff --git a/spec/services/bulk_upload/sales/year2024/csv_parser_spec.rb b/spec/services/bulk_upload/sales/year2024/csv_parser_spec.rb index 22bc73a9b..e4391212a 100644 --- a/spec/services/bulk_upload/sales/year2024/csv_parser_spec.rb +++ b/spec/services/bulk_upload/sales/year2024/csv_parser_spec.rb @@ -26,7 +26,7 @@ RSpec.describe BulkUpload::Sales::Year2024::CsvParser do end it "parses csv correctly" do - expect(service.row_parsers[0].field_19).to eql(log.uprn) + expect(service.row_parsers[0].field_22).to eql(log.uprn) end end @@ -51,7 +51,7 @@ RSpec.describe BulkUpload::Sales::Year2024::CsvParser do end it "parses csv correctly" do - expect(service.row_parsers[0].field_19).to eql(log.uprn) + expect(service.row_parsers[0].field_22).to eql(log.uprn) end end @@ -71,7 +71,7 @@ RSpec.describe BulkUpload::Sales::Year2024::CsvParser do end it "parses csv correctly" do - expect(service.row_parsers[0].field_19).to eql(log.uprn) + expect(service.row_parsers[0].field_22).to eql(log.uprn) end end @@ -88,7 +88,7 @@ RSpec.describe BulkUpload::Sales::Year2024::CsvParser do end it "parses csv correctly" do - expect(service.row_parsers[0].field_19).to eql(log.uprn) + expect(service.row_parsers[0].field_22).to eql(log.uprn) end end @@ -105,7 +105,7 @@ RSpec.describe BulkUpload::Sales::Year2024::CsvParser do end it "parses csv correctly" do - expect(service.row_parsers[0].field_19).to eql(log.uprn) + expect(service.row_parsers[0].field_22).to eql(log.uprn) end end @@ -124,24 +124,8 @@ RSpec.describe BulkUpload::Sales::Year2024::CsvParser do end it "returns correct column" do - expect(service.column_for_field("field_1")).to eql("CO") - expect(service.column_for_field("field_99")).to eql("EK") - end - end - - context "when no headers" do - let(:file) { Tempfile.new } - let(:path) { file.path } - let(:log) { build(:sales_log, :completed, :with_uprn) } - - before do - file.write(BulkUpload::SalesLogToCsv.new(log:, col_offset: 0).to_2024_csv_row) - file.rewind - end - - it "returns correct column" do - expect(service.column_for_field("field_1")).to eql("CN") - expect(service.column_for_field("field_99")).to eql("EJ") + expect(service.column_for_field("field_1")).to eql("B") + expect(service.column_for_field("field_99")).to eql("CV") end end end @@ -160,7 +144,7 @@ RSpec.describe BulkUpload::Sales::Year2024::CsvParser do end it "parses csv correctly" do - expect(service.row_parsers[0].field_19).to eql(log.uprn) + expect(service.row_parsers[0].field_22).to eql(log.uprn) end end end diff --git a/spec/services/bulk_upload/sales/year2024/row_parser_spec.rb b/spec/services/bulk_upload/sales/year2024/row_parser_spec.rb index ef92caa43..e50c5a62b 100644 --- a/spec/services/bulk_upload/sales/year2024/row_parser_spec.rb +++ b/spec/services/bulk_upload/sales/year2024/row_parser_spec.rb @@ -13,45 +13,49 @@ RSpec.describe BulkUpload::Sales::Year2024::RowParser do { bulk_upload:, field_1: owning_org.old_visible_id, # organisation - field_2: user.email, # user - field_3: now.day.to_s, # sale day - field_4: now.month.to_s, # sale month - field_5: now.strftime("%g"), # sale year - field_6: "test id", # purchase id - field_7: "1", # owhershipsch - field_8: "2", # shared ownership sale type - field_13: "1", # will the buyers live in the property - field_14: "2", # joint purchase + field_2: owning_org.old_visible_id, # organisation + field_3: user.email, # user + field_4: now.day.to_s, # sale day + field_5: now.month.to_s, # sale month + field_6: now.strftime("%g"), # sale year + field_7: "test id", # purchase id + field_8: "1", # owhershipsch + field_9: "2", # shared ownership sale type + field_14: "1", # will the buyers live in the property + field_15: "2", # joint purchase + field_17: "1", # noint + field_18: "1", # privacy notice } end let(:valid_attributes) do { bulk_upload:, - field_1: owning_org.old_visible_id, - field_3: "22", - field_4: "2", - field_5: "24", - field_6: "test id", - field_7: "1", - field_8: "2", - field_13: "1", + field_2: owning_org.old_visible_id, + + field_4: "12", + field_5: "5", + field_6: "24", + field_7: "test id", + field_8: "1", + field_9: "2", field_14: "1", - field_15: "2", + field_15: "1", field_16: "2", field_17: "1", field_18: "1", - field_19: "12", - field_24: "CR0", - field_25: "4BB", - field_26: "E09000008", - field_27: "3", - field_28: "1", - field_29: "1", - field_30: "32", - field_31: "M", - field_32: "12", - field_33: "18", + field_19: "2", + field_20: "1", + field_21: "1", + field_22: "12", + field_27: "CR0", + field_28: "4BB", + field_29: "E09000008", + field_30: "3", + field_31: "32", + field_32: "M", + field_33: "12", + field_34: "18", field_35: "1", field_36: "1", field_37: "R", @@ -59,54 +63,53 @@ RSpec.describe BulkUpload::Sales::Year2024::RowParser do field_39: "F", field_40: "17", field_41: "13", - field_43: "2", - field_44: "1", - field_45: "0", + field_42: "2", + field_43: "1", + field_44: "0", + field_61: "1", field_62: "1", - field_63: "1", - field_64: "A1", - field_65: "1AA", - field_66: "E09000008", + field_63: "A1", + field_64: "1AA", + field_65: "E09000008", + field_68: "1", field_69: "1", - field_70: "1", - field_71: "3", - field_73: "3", - field_75: "5", + field_70: "3", + field_72: "3", + field_74: "5", + field_75: "3", field_76: "3", - field_77: "3", - field_78: "30000", - field_79: "1", - field_80: "15000", - field_81: "1", - field_82: "4", - field_83: "20000", - field_84: "3", - field_86: "5", - field_87: "1", + field_77: "30000", + field_78: "1", + field_79: "15000", + field_80: "1", + field_81: "4", + field_82: "20000", + field_83: "3", + field_85: "5", + field_86: "1", + field_87: "10", field_88: "10", - field_89: "10", - field_90: "1", - field_92: "30", - field_93: "3", - field_94: "22", - field_95: "24", - field_96: "3", - field_97: "22", - field_98: "3", + field_89: "1", + field_91: "30", + field_92: "3", + field_93: "22", + field_94: "24", + field_95: "3", + field_96: "22", + field_97: "3", + field_98: "1", field_99: "1", field_100: "1", - field_101: "1", - field_102: "1", - field_103: "250000", - field_104: "25", + field_101: "250000", + field_102: "25", + field_103: "1", + field_104: "42500", field_105: "1", - field_106: "42500", - field_107: "1", - field_109: "20", - field_110: "3", - field_111: "20000", - field_113: "800", - field_114: "200", + field_107: "20", + field_108: "3", + field_109: "20000", + field_111: "800", + field_112: "200", } end @@ -155,11 +158,11 @@ RSpec.describe BulkUpload::Sales::Year2024::RowParser do end describe "previous postcode known" do - context "when field_63 is 1" do + context "when field_62 is 1" do let(:attributes) do { bulk_upload:, - field_63: 1, + field_62: 1, } end @@ -168,11 +171,11 @@ RSpec.describe BulkUpload::Sales::Year2024::RowParser do end end - context "when field_63 is 2" do + context "when field_62 is 2" do let(:attributes) do { bulk_upload:, - field_63: 2, + field_62: 2, } end @@ -200,7 +203,7 @@ RSpec.describe BulkUpload::Sales::Year2024::RowParser do end context "when calling the method multiple times" do - let(:attributes) { { bulk_upload:, field_7: 2 } } + let(:attributes) { { bulk_upload:, field_8: 2 } } it "does not add keep adding errors to the pile" do expect { parser.valid? }.not_to change(parser.errors, :count) @@ -229,14 +232,14 @@ RSpec.describe BulkUpload::Sales::Year2024::RowParser do let(:attributes) do { bulk_upload:, - field_6: "test id", + field_7: "test id", } end it "has errors on correct setup fields" do errors = parser.errors.select { |e| e.options[:category] == :setup }.map(&:attribute).sort - expect(errors).to eql(%i[field_1 field_29 field_3 field_4 field_5 field_7]) + expect(errors).to eql(%i[field_1 field_18 field_4 field_5 field_6 field_8]) end end @@ -244,15 +247,15 @@ RSpec.describe BulkUpload::Sales::Year2024::RowParser do let(:attributes) do { bulk_upload:, - field_6: "test id", - field_7: "1", + field_7: "test id", + field_8: "1", } end it "has errors on correct setup fields" do errors = parser.errors.select { |e| e.options[:category] == :setup }.map(&:attribute).sort - expect(errors).to eql(%i[field_1 field_14 field_29 field_3 field_4 field_5 field_8]) + expect(errors).to eql(%i[field_1 field_15 field_18 field_4 field_5 field_6 field_9]) end end @@ -260,17 +263,17 @@ RSpec.describe BulkUpload::Sales::Year2024::RowParser do let(:attributes) do { bulk_upload:, - field_6: "test id", - field_7: "1", - field_8: "2", - field_14: "1", + field_7: "test id", + field_8: "1", + field_9: "2", + field_15: "1", } end it "has errors on correct setup fields" do errors = parser.errors.select { |e| e.options[:category] == :setup }.map(&:attribute).sort - expect(errors).to eql(%i[field_1 field_15 field_29 field_3 field_4 field_5]) + expect(errors).to eql(%i[field_1 field_16 field_18 field_4 field_5 field_6]) end end @@ -278,15 +281,16 @@ RSpec.describe BulkUpload::Sales::Year2024::RowParser do let(:attributes) do { bulk_upload:, - field_6: "test id", - field_7: "2", + field_7: "test id", + field_8: "2", + field_10: nil, } end it "has errors on correct setup fields" do errors = parser.errors.select { |e| e.options[:category] == :setup }.map(&:attribute).sort - expect(errors).to eql(%i[field_1 field_14 field_29 field_3 field_4 field_5 field_9]) + expect(errors).to eql(%i[field_1 field_10 field_15 field_18 field_4 field_5 field_6]) end end @@ -294,9 +298,9 @@ RSpec.describe BulkUpload::Sales::Year2024::RowParser do let(:attributes) do { bulk_upload:, - field_28: "test id", - field_30: "2", - field_47: "8", + field_17: "test id", + field_31: "2", + field_46: "8", field_39: "1", } end @@ -304,7 +308,7 @@ RSpec.describe BulkUpload::Sales::Year2024::RowParser do it "has errors on correct setup fields" do errors = parser.errors.select { |e| e.options[:category] == :setup }.map(&:attribute).sort - expect(errors).to eql(%i[field_1 field_29 field_3 field_4 field_5 field_7]) + expect(errors).to eql(%i[field_1 field_18 field_4 field_5 field_6 field_8]) end end @@ -312,15 +316,15 @@ RSpec.describe BulkUpload::Sales::Year2024::RowParser do let(:attributes) do { bulk_upload:, - field_6: "test id", - field_7: "3", + field_7: "test id", + field_8: "3", } end it "has errors on correct setup fields" do errors = parser.errors.select { |e| e.options[:category] == :setup }.map(&:attribute).sort - expect(errors).to eql(%i[field_1 field_10 field_12 field_13 field_29 field_3 field_4 field_5]) + expect(errors).to eql(%i[field_1 field_11 field_13 field_14 field_18 field_4 field_5 field_6]) end end @@ -328,17 +332,17 @@ RSpec.describe BulkUpload::Sales::Year2024::RowParser do let(:attributes) do { bulk_upload:, - field_6: "test id", - field_7: "3", - field_10: "12", - field_12: "2", + field_7: "test id", + field_8: "3", + field_11: "12", + field_13: "2", } end it "has errors on correct setup fields" do errors = parser.errors.select { |e| e.options[:category] == :setup }.map(&:attribute).sort - expect(errors).to eql(%i[field_1 field_11 field_13 field_14 field_29 field_3 field_4 field_5]) + expect(errors).to eql(%i[field_1 field_12 field_14 field_15 field_18 field_4 field_5 field_6]) end end @@ -403,7 +407,7 @@ RSpec.describe BulkUpload::Sales::Year2024::RowParser do context "when user's org has absorbed owning organisation" do let(:merged_org) { create(:organisation, :with_old_visible_id, holds_own_stock: true) } - let(:attributes) { { bulk_upload:, field_1: merged_org.old_visible_id, field_2: user.email } } + let(:attributes) { { bulk_upload:, field_1: merged_org.old_visible_id, field_3: user.email } } before do merged_org.update!(absorbing_organisation: user.organisation, merge_date: Time.zone.today) @@ -417,14 +421,14 @@ RSpec.describe BulkUpload::Sales::Year2024::RowParser do parser.valid? expect(parser.errors.where(:field_1)).not_to be_present - expect(parser.errors.where(:field_2)).not_to be_present + expect(parser.errors.where(:field_3)).not_to be_present end end context "when user's org has absorbed owning organisation before the startdate" do let(:merged_org) { create(:organisation, :with_old_visible_id, holds_own_stock: true) } - let(:attributes) { setup_section_params.merge({ field_1: merged_org.old_visible_id, field_2: user.email }) } + let(:attributes) { setup_section_params.merge({ field_1: merged_org.old_visible_id, field_3: user.email }) } before do merged_org.update!(absorbing_organisation: user.organisation, merge_date: Time.zone.today - 3.years) @@ -438,37 +442,37 @@ RSpec.describe BulkUpload::Sales::Year2024::RowParser do parser.valid? expect(parser.errors[:field_1]).to include(/The owning organisation must be active on the sale completion date/) - expect(parser.errors[:field_3]).to include(/Enter a date when the owning organisation was active/) expect(parser.errors[:field_4]).to include(/Enter a date when the owning organisation was active/) expect(parser.errors[:field_5]).to include(/Enter a date when the owning organisation was active/) + expect(parser.errors[:field_6]).to include(/Enter a date when the owning organisation was active/) end end end - describe "#field_2" do # username for created_by + describe "#field_3" do # username for created_by context "when blank" do - let(:attributes) { setup_section_params.merge(bulk_upload:, field_2: nil) } + let(:attributes) { setup_section_params.merge(bulk_upload:, field_3: nil) } it "is permitted" do - expect(parser.errors[:field_2]).to be_blank + expect(parser.errors[:field_3]).to be_blank end end context "when user could not be found" do - let(:attributes) { { bulk_upload:, field_2: "idonotexist@example.com" } } + let(:attributes) { { bulk_upload:, field_3: "idonotexist@example.com" } } it "is not permitted" do - expect(parser.errors[:field_2]).to be_present + expect(parser.errors[:field_3]).to be_present end end context "when an unaffiliated user" do let(:other_user) { create(:user) } - let(:attributes) { { bulk_upload:, field_1: owning_org.old_visible_id, field_2: other_user.email } } + let(:attributes) { { bulk_upload:, field_1: owning_org.old_visible_id, field_3: other_user.email } } it "is not permitted as a setup error" do - expect(parser.errors.where(:field_2, category: :setup)).to be_present + expect(parser.errors.where(:field_3, category: :setup)).to be_present end it "blocks log creation" do @@ -479,55 +483,55 @@ RSpec.describe BulkUpload::Sales::Year2024::RowParser do context "when an user part of owning org" do let(:other_user) { create(:user, organisation: owning_org) } - let(:attributes) { { bulk_upload:, field_1: owning_org.old_visible_id, field_2: other_user.email } } + let(:attributes) { { bulk_upload:, field_1: owning_org.old_visible_id, field_3: other_user.email } } it "is permitted" do - expect(parser.errors[:field_2]).to be_blank + expect(parser.errors[:field_3]).to be_blank end end context "when email matches other than casing" do let(:other_user) { create(:user, organisation: owning_org) } - let(:attributes) { { bulk_upload:, field_1: owning_org.old_visible_id, field_2: other_user.email.upcase! } } + let(:attributes) { { bulk_upload:, field_1: owning_org.old_visible_id, field_3: other_user.email.upcase! } } it "is permitted" do - expect(parser.errors[:field_2]).to be_blank + expect(parser.errors[:field_3]).to be_blank end end end describe "fields 3, 4, 5 => saledate" do context "when all of these fields are blank" do - let(:attributes) { setup_section_params.merge({ field_3: nil, field_4: nil, field_5: nil }) } + let(:attributes) { setup_section_params.merge({ field_4: nil, field_5: nil, field_6: nil }) } it "returns them as setup errors" do - expect(parser.errors.where(:field_3, category: :setup)).to be_present expect(parser.errors.where(:field_4, category: :setup)).to be_present expect(parser.errors.where(:field_5, category: :setup)).to be_present + expect(parser.errors.where(:field_6, category: :setup)).to be_present end end context "when one of these fields is blank" do - let(:attributes) { setup_section_params.merge({ field_3: "1", field_4: "1", field_5: nil }) } + let(:attributes) { setup_section_params.merge({ field_4: "1", field_5: "1", field_6: nil }) } it "returns an error only on blank field as setup error" do - expect(parser.errors[:field_3]).to be_blank expect(parser.errors[:field_4]).to be_blank - expect(parser.errors.where(:field_5, category: :setup)).to be_present + expect(parser.errors[:field_5]).to be_blank + expect(parser.errors.where(:field_6, category: :setup)).to be_present end end context "when field 5 is 4 digits instead of 2" do - let(:attributes) { setup_section_params.merge({ bulk_upload:, field_5: "2023" }) } + let(:attributes) { setup_section_params.merge({ bulk_upload:, field_6: "2023" }) } it "returns a setup error" do - expect(parser.errors.where(:field_5, category: :setup).map(&:message)).to include("Sale completion year must be 2 digits") + expect(parser.errors.where(:field_6, category: :setup).map(&:message)).to include("Sale completion year must be 2 digits") end end context "when invalid date given" do - let(:attributes) { setup_section_params.merge({ field_3: "a", field_4: "12", field_5: "2023" }) } + let(:attributes) { setup_section_params.merge({ field_4: "a", field_5: "12", field_6: "2023" }) } it "does not raise an error" do expect { parser.valid? }.not_to raise_error @@ -541,14 +545,14 @@ RSpec.describe BulkUpload::Sales::Year2024::RowParser do end end - let(:attributes) { setup_section_params.merge({ field_3: "1", field_4: "10", field_5: "23" }) } + let(:attributes) { setup_section_params.merge({ field_4: "1", field_5: "10", field_6: "24" }) } let(:bulk_upload) { create(:bulk_upload, :sales, user:, year: 2024) } it "does not return errors" do - expect(parser.errors[:field_3]).not_to be_present expect(parser.errors[:field_4]).not_to be_present expect(parser.errors[:field_5]).not_to be_present + expect(parser.errors[:field_6]).not_to be_present end end @@ -559,14 +563,14 @@ RSpec.describe BulkUpload::Sales::Year2024::RowParser do end end - let(:attributes) { setup_section_params.merge({ field_3: "1", field_4: "1", field_5: "22" }) } + let(:attributes) { setup_section_params.merge({ field_4: "1", field_5: "1", field_6: "22" }) } let(:bulk_upload) { create(:bulk_upload, :sales, user:, year: 2023) } it "returns setup errors" do - expect(parser.errors.where(:field_3, category: :setup)).to be_present expect(parser.errors.where(:field_4, category: :setup)).to be_present expect(parser.errors.where(:field_5, category: :setup)).to be_present + expect(parser.errors.where(:field_6, category: :setup)).to be_present end end end @@ -590,15 +594,15 @@ RSpec.describe BulkUpload::Sales::Year2024::RowParser do [ :field_1, # Owning org - :field_3, # Sale completion date :field_4, # Sale completion date :field_5, # Sale completion date - :field_24, # Postcode - :field_25, # Postcode - :field_30, # Buyer 1 age - :field_31, # Buyer 1 gender + :field_6, # Sale completion date + :field_27, # Postcode + :field_28, # Postcode + :field_31, # Buyer 1 age + :field_32, # Buyer 1 gender :field_35, # Buyer 1 working situation - :field_6, # Purchaser code + :field_7, # Purchaser code ].each do |field| expect(parser.errors[field]).to include(error_message) end @@ -621,32 +625,22 @@ RSpec.describe BulkUpload::Sales::Year2024::RowParser do [ :field_1, # Owning org - :field_3, # Sale completion date :field_4, # Sale completion date :field_5, # Sale completion date - :field_24, # Postcode - :field_25, # Postcode - :field_30, # Buyer 1 age - :field_31, # Buyer 1 gender + :field_6, # Sale completion date + :field_27, # Postcode + :field_28, # Postcode + :field_31, # Buyer 1 age + :field_32, # Buyer 1 gender :field_35, # Buyer 1 working situation - :field_6, # Purchaser code + :field_7, # Purchaser code ].each do |field| expect(parser.errors[field]).to be_blank end end end - describe "#field_7" do # ownership scheme - context "when an invalid option" do - let(:attributes) { setup_section_params.merge({ field_7: "100" }) } - - it "returns setup error" do - expect(parser.errors.where(:field_7, category: :setup)).to be_present - end - end - end - - describe "#field_8" do # type for shared ownership sale + describe "#field_8" do # ownership scheme context "when an invalid option" do let(:attributes) { setup_section_params.merge({ field_8: "100" }) } @@ -656,7 +650,7 @@ RSpec.describe BulkUpload::Sales::Year2024::RowParser do end end - describe "#field_9" do # type for discounted sale + describe "#field_9" do # type for shared ownership sale context "when an invalid option" do let(:attributes) { setup_section_params.merge({ field_9: "100" }) } @@ -666,7 +660,7 @@ RSpec.describe BulkUpload::Sales::Year2024::RowParser do end end - describe "#field_10" do # type for outright sale + describe "#field_10" do # type for discounted sale context "when an invalid option" do let(:attributes) { setup_section_params.merge({ field_10: "100" }) } @@ -676,9 +670,9 @@ RSpec.describe BulkUpload::Sales::Year2024::RowParser do end end - describe "#field_11" do # type of other outright sale + describe "#field_11" do # type for outright sale context "when an invalid option" do - let(:attributes) { setup_section_params.merge({ field_10: "12", field_11: nil }) } + let(:attributes) { setup_section_params.merge({ field_11: "100" }) } it "returns setup error" do expect(parser.errors.where(:field_11, category: :setup)).to be_present @@ -686,41 +680,41 @@ RSpec.describe BulkUpload::Sales::Year2024::RowParser do end end - describe "#field_12" do # buyer a company? + describe "#field_12" do # type of other outright sale context "when an invalid option" do - let(:attributes) { setup_section_params.merge({ field_7: "3", field_12: "100" }) } + let(:attributes) { setup_section_params.merge({ field_11: "12", field_12: nil }) } it "returns setup error" do - expect(parser.errors.where(:field_12).map(&:message)).to include("Enter a valid value for is the buyer a company?") expect(parser.errors.where(:field_12, category: :setup)).to be_present end end end - describe "#field_13" do # will buyers live in the property? + describe "#field_13" do # buyer a company? context "when an invalid option" do - let(:attributes) { setup_section_params.merge({ field_7: "3", field_13: "100" }) } + let(:attributes) { setup_section_params.merge({ field_8: "3", field_13: "100" }) } it "returns setup error" do - expect(parser.errors.where(:field_13).map(&:message)).to eql(["Enter a valid value for will the buyers live in the property?"]) + expect(parser.errors.where(:field_13).map(&:message)).to include("Enter a valid value for is the buyer a company?") expect(parser.errors.where(:field_13, category: :setup)).to be_present end end end - describe "#field_14" do # joint purchase + describe "#field_14" do # will buyers live in the property? context "when an invalid option" do - let(:attributes) { setup_section_params.merge({ field_14: "100" }) } + let(:attributes) { setup_section_params.merge({ field_8: "3", field_14: "100" }) } - it "returns a setup error" do + it "returns setup error" do + expect(parser.errors.where(:field_14).map(&:message)).to eql(["Enter a valid value for will the buyers live in the property?"]) expect(parser.errors.where(:field_14, category: :setup)).to be_present end end end - describe "#field_15" do # more than 2 joint buyers? - context "when invalid option and must be answered" do - let(:attributes) { setup_section_params.merge({ field_14: "1", field_15: "100" }) } + describe "#field_15" do # joint purchase + context "when an invalid option" do + let(:attributes) { setup_section_params.merge({ field_15: "100" }) } it "returns a setup error" do expect(parser.errors.where(:field_15, category: :setup)).to be_present @@ -728,12 +722,22 @@ RSpec.describe BulkUpload::Sales::Year2024::RowParser do end end - describe "#field_19" do # UPRN + describe "#field_16" do # more than 2 joint buyers? + context "when invalid option and must be answered" do + let(:attributes) { setup_section_params.merge({ field_15: "1", field_16: "100" }) } + + it "returns a setup error" do + expect(parser.errors.where(:field_16, category: :setup)).to be_present + end + end + end + + describe "#field_22" do # UPRN context "when UPRN known and lookup found" do - let(:attributes) { setup_section_params.merge({ field_19: "12" }) } + let(:attributes) { setup_section_params.merge({ field_22: "12" }) } it "is valid" do - expect(parser.errors[:field_19]).to be_blank + expect(parser.errors[:field_22]).to be_blank end it "sets UPRN and UPRN known" do @@ -744,38 +748,38 @@ RSpec.describe BulkUpload::Sales::Year2024::RowParser do end context "when UPRN not known but address known" do - let(:attributes) { setup_section_params.merge({ field_19: nil, field_20: "some street", field_22: "some town", field_24: "EC1N", field_25: "2TD" }) } + let(:attributes) { setup_section_params.merge({ field_22: nil, field_23: "some street", field_25: "some town", field_27: "EC1N", field_28: "2TD" }) } it "is valid" do - expect(parser.errors[:field_19]).to be_blank + expect(parser.errors[:field_22]).to be_blank end end context "when neither UPRN or address known" do - let(:attributes) { setup_section_params.merge({ field_19: nil, field_20: nil, field_22: nil, field_24: nil, field_25: nil }) } + let(:attributes) { setup_section_params.merge({ field_22: nil, field_23: nil, field_25: nil, field_27: nil, field_28: nil }) } it "is not valid" do - expect(parser.errors[:field_19]).to be_present + expect(parser.errors[:field_22]).to be_present end end context "when UPRN entered but no lookup found" do - let(:attributes) { setup_section_params.merge({ field_19: "1234567890123" }) } + let(:attributes) { setup_section_params.merge({ field_22: "1234567890123" }) } it "is not valid" do - expect(parser.errors[:field_19]).to be_present + expect(parser.errors[:field_22]).to be_present end end end [ - { field: :field_20, name: "address line 1" }, - { field: :field_22, name: "town or city" }, + { field: :field_23, name: "address line 1" }, + { field: :field_25, name: "town or city" }, ].each do |data| describe "##{data[:field]} (#{data[:name]})" do context "when UPRN present" do context "when UPRN valid" do - let(:attributes) { setup_section_params.merge({ field_19: "12", data[:field] => nil }) } + let(:attributes) { setup_section_params.merge({ field_22: "12", data[:field] => nil }) } it "can be blank" do expect(parser.errors[data[:field]]).to be_blank @@ -783,7 +787,7 @@ RSpec.describe BulkUpload::Sales::Year2024::RowParser do end context "when UPRN invalid" do - let(:attributes) { setup_section_params.merge({ field_19: "1234567890123", data[:field] => nil }) } + let(:attributes) { setup_section_params.merge({ field_22: "1234567890123", data[:field] => nil }) } it "cannot be blank" do expect(parser.errors[data[:field]]).to be_present @@ -792,7 +796,7 @@ RSpec.describe BulkUpload::Sales::Year2024::RowParser do end context "when UPRN not present" do - let(:attributes) { setup_section_params.merge({ field_19: nil, data[:field] => nil }) } + let(:attributes) { setup_section_params.merge({ field_22: nil, data[:field] => nil }) } it "cannot be blank" do expect(parser.errors[data[:field]]).to be_present @@ -801,28 +805,28 @@ RSpec.describe BulkUpload::Sales::Year2024::RowParser do end end - describe "#field_29" do # data protection - let(:attributes) { setup_section_params.merge({ field_29: nil }) } + describe "#field_18" do # data protection + let(:attributes) { setup_section_params.merge({ field_18: nil }) } context "when not answered" do it "returns a setup error" do - expect(parser.errors.where(:field_29, category: :setup)).to be_present + expect(parser.errors.where(:field_18, category: :setup)).to be_present end end end [ - %w[age1_known details_known_1 age1 field_30 field_37 field_39], + %w[age1_known details_known_1 age1 field_31 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_47 field_46 field_48], - %w[age4_known details_known_4 age4 field_51 field_50 field_52], - %w[age5_known details_known_5 age5 field_55 field_54 field_56], - %w[age6_known details_known_6 age6 field_59 field_58 field_60], + %w[age3_known details_known_3 age3 field_46 field_45 field_47], + %w[age4_known details_known_4 age4 field_50 field_49 field_51], + %w[age5_known details_known_5 age5 field_54 field_53 field_55], + %w[age6_known details_known_6 age6 field_58 field_57 field_59], ].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_29: "1", field_45: "5" }) } + let(:attributes) { setup_section_params.merge({ field.to_s => nil, relationship.to_sym => nil, gender.to_sym => nil, field_18: "1", field_44: "5" }) } it "does not set ##{known}" do unless known == "age1_known" @@ -842,7 +846,7 @@ RSpec.describe BulkUpload::Sales::Year2024::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_29: "1", field_45: "5" }) } + let(:attributes) { setup_section_params.merge({ field.to_sym => nil, relationship.to_sym => "C", gender.to_sym => "X", field_18: "1", field_44: "5" }) } it "does not set ##{age}" do parser.valid? @@ -852,7 +856,7 @@ RSpec.describe BulkUpload::Sales::Year2024::RowParser do end context "when #{field} is R" do - let(:attributes) { setup_section_params.merge({ field.to_s => "R", field_28: "1", field_45: "5", field_29: "1" }) } + let(:attributes) { setup_section_params.merge({ field.to_s => "R", field_17: "1", field_44: "5", field_18: "1" }) } it "sets ##{known} 1" do expect(parser.log.public_send(known)).to be(1) @@ -864,7 +868,7 @@ RSpec.describe BulkUpload::Sales::Year2024::RowParser do end context "when #{field} is a number" do - let(:attributes) { setup_section_params.merge({ field.to_s => "50", field_28: "1", field_45: "5", field_29: "1" }) } + let(:attributes) { setup_section_params.merge({ field.to_s => "50", field_17: "1", field_44: "5", field_18: "1" }) } it "sets ##{known} to 0" do expect(parser.log.public_send(known)).to be(0) @@ -876,7 +880,7 @@ RSpec.describe BulkUpload::Sales::Year2024::RowParser do end context "when #{field} is a non-sensical value" do - let(:attributes) { setup_section_params.merge({ field.to_s => "A", field_28: "1", field_45: "5", field_29: "1" }) } + let(:attributes) { setup_section_params.merge({ field.to_s => "A", field_17: "1", field_44: "5", field_18: "1" }) } it "sets ##{known} to 0" do expect(parser.log.public_send(known)).to be(0) @@ -910,39 +914,39 @@ RSpec.describe BulkUpload::Sales::Year2024::RowParser do end end - describe "#field_67 - 70" do # buyers organisations + describe "#field_66 - 70" do # buyers organisations context "when all nil" do - let(:attributes) { setup_section_params.merge(field_67: nil, field_68: nil, field_69: nil, field_70: nil) } + let(:attributes) { setup_section_params.merge(field_66: nil, field_67: nil, field_68: nil, field_69: nil) } it "returns correct errors" do + expect(parser.errors[:field_66]).to be_present expect(parser.errors[:field_67]).to be_present expect(parser.errors[:field_68]).to be_present expect(parser.errors[:field_69]).to be_present - expect(parser.errors[:field_70]).to be_present end end end describe "soft validations" do context "when soft validation is triggered" do - let(:attributes) { valid_attributes.merge({ field_30: 22, field_35: 5 }) } + let(:attributes) { valid_attributes.merge({ field_31: 22, field_35: 5 }) } it "adds an error to the relevant fields" do - expect(parser.errors.where(:field_30, category: :soft_validation)).to be_present + expect(parser.errors.where(:field_31, 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 - expect(parser.errors.where(:field_30, category: :soft_validation).first.message).to eql("You told us this person is aged 22 years and retired.") - expect(parser.errors.where(:field_30, category: :soft_validation).first.message).to eql("You told us this person is aged 22 years and retired.") + expect(parser.errors.where(:field_31, category: :soft_validation).first.message).to eql("You told us this person is aged 22 years and retired.") + expect(parser.errors.where(:field_31, category: :soft_validation).first.message).to eql("You told us this person is aged 22 years and retired.") end end context "when a soft validation is triggered that relates both to fields that are and are not routed to" do - let(:attributes) { valid_attributes.merge({ field_103: "300000" }) } + let(:attributes) { valid_attributes.merge({ field_101: "300000" }) } it "adds errors to fields that are routed to" do - expect(parser.errors.where(:field_103, category: :soft_validation)).to be_present + expect(parser.errors.where(:field_101, category: :soft_validation)).to be_present end it "does not add errors to fields that are not routed to" do @@ -954,7 +958,7 @@ RSpec.describe BulkUpload::Sales::Year2024::RowParser do describe "#log" do describe "#uprn" do - let(:attributes) { setup_section_params.merge({ field_19: "12" }) } + let(:attributes) { setup_section_params.merge({ field_22: "12" }) } it "is correctly set" do expect(parser.log.uprn).to eql("12") @@ -963,7 +967,7 @@ RSpec.describe BulkUpload::Sales::Year2024::RowParser do describe "#uprn_known" do context "when uprn known" do - let(:attributes) { setup_section_params.merge({ field_19: "12" }) } + let(:attributes) { setup_section_params.merge({ field_22: "12" }) } it "is correctly set" do expect(parser.log.uprn_known).to be(1) @@ -971,7 +975,7 @@ RSpec.describe BulkUpload::Sales::Year2024::RowParser do end context "when uprn not known" do - let(:attributes) { setup_section_params.merge({ field_19: nil }) } + let(:attributes) { setup_section_params.merge({ field_22: nil }) } it "is correctly set" do expect(parser.log.uprn_known).to be(0) @@ -980,7 +984,7 @@ RSpec.describe BulkUpload::Sales::Year2024::RowParser do end describe "#address_line1" do - let(:attributes) { setup_section_params.merge({ field_20: "some street" }) } + let(:attributes) { setup_section_params.merge({ field_23: "some street" }) } it "is correctly set" do expect(parser.log.address_line1).to eql("some street") @@ -988,7 +992,7 @@ RSpec.describe BulkUpload::Sales::Year2024::RowParser do end describe "#address_line2" do - let(:attributes) { setup_section_params.merge({ field_21: "some other street" }) } + let(:attributes) { setup_section_params.merge({ field_24: "some other street" }) } it "is correctly set" do expect(parser.log.address_line2).to eql("some other street") @@ -996,7 +1000,7 @@ RSpec.describe BulkUpload::Sales::Year2024::RowParser do end describe "#town_or_city" do - let(:attributes) { setup_section_params.merge({ field_22: "some town" }) } + let(:attributes) { setup_section_params.merge({ field_25: "some town" }) } it "is correctly set" do expect(parser.log.town_or_city).to eql("some town") @@ -1004,7 +1008,7 @@ RSpec.describe BulkUpload::Sales::Year2024::RowParser do end describe "#county" do - let(:attributes) { setup_section_params.merge({ field_23: "some county" }) } + let(:attributes) { setup_section_params.merge({ field_26: "some county" }) } it "is correctly set" do expect(parser.log.county).to eql("some county") @@ -1036,7 +1040,7 @@ RSpec.describe BulkUpload::Sales::Year2024::RowParser do end describe "#buy2living" do - let(:attributes) { setup_section_params.merge({ field_71: "1" }) } + let(:attributes) { setup_section_params.merge({ field_70: "1" }) } it "is correctly set" do expect(parser.log.buy2living).to be(1) @@ -1044,7 +1048,7 @@ RSpec.describe BulkUpload::Sales::Year2024::RowParser do end describe "#prevtenbuy2" do - let(:attributes) { setup_section_params.merge({ field_72: "R" }) } + let(:attributes) { setup_section_params.merge({ field_71: "R" }) } it "is correctly set" do expect(parser.log.prevtenbuy2).to be(0) @@ -1052,7 +1056,7 @@ RSpec.describe BulkUpload::Sales::Year2024::RowParser do end describe "#hhregres" do - let(:attributes) { setup_section_params.merge({ field_73: "1" }) } + let(:attributes) { setup_section_params.merge({ field_72: "1" }) } it "is correctly set" do expect(parser.log.hhregres).to be(1) @@ -1060,7 +1064,7 @@ RSpec.describe BulkUpload::Sales::Year2024::RowParser do end describe "#hhregresstill" do - let(:attributes) { setup_section_params.merge({ field_74: "4" }) } + let(:attributes) { setup_section_params.merge({ field_73: "4" }) } it "is correctly set" do expect(parser.log.hhregresstill).to be(4) @@ -1068,7 +1072,7 @@ RSpec.describe BulkUpload::Sales::Year2024::RowParser do end describe "#prevshared" do - let(:attributes) { setup_section_params.merge({ field_85: "3" }) } + let(:attributes) { setup_section_params.merge({ field_84: "3" }) } it "is correctly set" do expect(parser.log.prevshared).to be(3) @@ -1076,7 +1080,7 @@ RSpec.describe BulkUpload::Sales::Year2024::RowParser do end describe "#staircasesale" do - let(:attributes) { setup_section_params.merge({ field_90: "1" }) } + let(:attributes) { setup_section_params.merge({ field_89: "1" }) } it "is correctly set" do expect(parser.log.staircasesale).to be(1) @@ -1092,7 +1096,7 @@ RSpec.describe BulkUpload::Sales::Year2024::RowParser do end describe "with living before purchase years for shared ownership more than 0" do - let(:attributes) { setup_section_params.merge({ field_7: "1", field_86: "1" }) } + let(:attributes) { setup_section_params.merge({ field_8: "1", field_85: "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) @@ -1101,7 +1105,7 @@ RSpec.describe BulkUpload::Sales::Year2024::RowParser do end describe "with living before purchase years for discounted ownership more than 0" do - let(:attributes) { setup_section_params.merge({ field_7: "2", field_115: "1" }) } + let(:attributes) { setup_section_params.merge({ field_8: "2", field_113: "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) @@ -1110,7 +1114,7 @@ RSpec.describe BulkUpload::Sales::Year2024::RowParser do end describe "with living before purchase years for shared ownership set to 0" do - let(:attributes) { setup_section_params.merge({ field_7: "1", field_86: "0" }) } + let(:attributes) { setup_section_params.merge({ field_8: "1", field_85: "0" }) } it "is sets living before purchase asked to no" do expect(parser.log.proplen_asked).to be(1) @@ -1119,7 +1123,7 @@ RSpec.describe BulkUpload::Sales::Year2024::RowParser do end describe "with living before purchase 0 years for discounted ownership set to 0" do - let(:attributes) { setup_section_params.merge({ field_7: "2", field_115: "0" }) } + let(:attributes) { setup_section_params.merge({ field_8: "2", field_113: "0" }) } it "is sets living before purchase asked to no" do expect(parser.log.proplen_asked).to be(1) @@ -1128,7 +1132,7 @@ RSpec.describe BulkUpload::Sales::Year2024::RowParser do end context "when mscharge is given, but is set to 0 for shared ownership" do - let(:attributes) { valid_attributes.merge(field_114: "0") } + let(:attributes) { valid_attributes.merge(field_112: "0") } it "does not override variables correctly" do log = parser.log @@ -1138,7 +1142,7 @@ RSpec.describe BulkUpload::Sales::Year2024::RowParser do end context "when mscharge is given, but is set to 0 for discounted ownership" do - let(:attributes) { valid_attributes.merge(field_7: "2", field_126: "0") } + let(:attributes) { valid_attributes.merge(field_8: "2", field_124: "0") } it "does not override variables correctly" do log = parser.log @@ -1148,7 +1152,7 @@ RSpec.describe BulkUpload::Sales::Year2024::RowParser do end context "when mscharge is given, but is set to 0 for outright sale" do - let(:attributes) { valid_attributes.merge(field_7: "3", field_135: "0") } + let(:attributes) { valid_attributes.merge(field_8: "3", field_131: "0") } it "does not override variables correctly" do log = parser.log @@ -1159,7 +1163,7 @@ RSpec.describe BulkUpload::Sales::Year2024::RowParser do describe "shared ownership sale type" do context "when 32 is selected for shared ownership type" do - let(:attributes) { valid_attributes.merge(field_8: "32") } + let(:attributes) { valid_attributes.merge(field_9: "32") } it "sets the value correctly" do log = parser.log @@ -1204,7 +1208,7 @@ RSpec.describe BulkUpload::Sales::Year2024::RowParser do parser.valid? setup_errors = parser.errors.select { |e| e.options[:category] == :setup } - expect(setup_errors.find { |e| e.attribute == :field_2 }.message).to eql("This user belongs to an organisation that does not have a relationship with the owning organisation") + expect(setup_errors.find { |e| e.attribute == :field_3 }.message).to eql("This user belongs to an organisation that does not have a relationship with the owning organisation") end it "blocks log creation" do diff --git a/spec/support/bulk_upload/sales_log_to_csv.rb b/spec/support/bulk_upload/sales_log_to_csv.rb index eb32bb822..e5f62e52a 100644 --- a/spec/support/bulk_upload/sales_log_to_csv.rb +++ b/spec/support/bulk_upload/sales_log_to_csv.rb @@ -25,6 +25,15 @@ class BulkUpload::SalesLogToCsv end end + def to_2024_csv_row(seed: nil) + if seed + row = to_2024_row.shuffle(random: Random.new(seed)) + (row_prefix + row).flatten.join(",") + line_ending + else + (row_prefix + to_2024_row).flatten.join(",") + line_ending + end + end + def default_2022_field_numbers (1..125).to_a end @@ -45,6 +54,14 @@ class BulkUpload::SalesLogToCsv end.flatten.join(",") + line_ending end + def default_2024_field_numbers_row(seed: nil) + if seed + ["Bulk upload field number"] + default_2024_field_numbers.shuffle(random: Random.new(seed)) + else + ["Bulk upload field number"] + default_2024_field_numbers + end.flatten.join(",") + line_ending + end + def to_2023_row to_2022_row + [ log.uprn, @@ -212,6 +229,154 @@ class BulkUpload::SalesLogToCsv ] end + def to_2024_row + [ + overrides[:organisation_id] || log.owning_organisation&.old_visible_id, + log.managing_organisation, + log.created_by&.email, + log.saledate&.day, + log.saledate&.month, + log.saledate&.strftime("%y"), + log.purchid, + log.ownershipsch, + log.type, # field_9: "What is the type of shared ownership sale?", + log.type, # field_10: "What is the type of discounted ownership sale?", + + log.type, # field_11: "What is the type of outright sale?", + log.othtype, + log.companybuy, + log.buylivein, + log.jointpur, + log.jointmore, + log.noint, + log.privacynotice, + log.beds, + log.proptype, # 20 + + log.builtype, + log.uprn, + log.address_line1, + log.address_line2, + log.town_or_city, + log.county, + ((log.postcode_full || "").split(" ") || [""]).first, + ((log.postcode_full || "").split(" ") || [""]).last, + log.la, + log.wchair, # 30 + + log.age1, + log.sex1, + log.ethnic, + log.national, + log.ecstat1, + log.buy1livein, + log.relat2, + log.age2, + log.sex2, + log.ethnic_group2, # 40 + + log.nationalbuy2, + log.ecstat2, + log.buy2livein, + log.hholdcount, + log.relat3, + log.age3, + log.sex3, + log.ecstat3, + log.relat4, + log.age4, # 50 + + log.sex4, + log.ecstat4, + log.relat5, + log.age5, + log.sex5, + log.ecstat5, + log.relat6, + log.age6, + log.sex6, + log.ecstat6, # 60 + + log.prevten, + log.ppcodenk, + ((log.ppostcode_full || "").split(" ") || [""]).first, + ((log.ppostcode_full || "").split(" ") || [""]).last, + log.prevloc, + log.pregyrha, + log.pregother, + log.pregla, + log.pregghb, + log.buy2living, # 70 + + log.prevtenbuy2, + hhregres, + log.hhregresstill, + log.armedforcesspouse, + log.disabled, + log.wheel, + log.income1, + log.inc1mort, + log.income2, + log.inc2mort, # 80 + + log.hb, + log.savings, + log.prevown, + log.prevshared, + log.proplen, + log.staircase, + log.stairbought, + log.stairowned, + log.staircasesale, + log.resale, # 90 + + log.exdate&.day, + log.exdate&.month, + log.exdate&.strftime("%y"), + log.hodate&.day, + log.hodate&.month, # 60 + log.hodate&.strftime("%y"), + log.lanomagr, + log.frombeds, + log.fromprop, + log.socprevten, # 100 + + log.value, + log.equity, + log.mortgageused, + log.mortgage, + log.mortgagelender, + log.mortgagelenderother, + log.mortlen, + log.extrabor, + log.deposit, + log.cashdis, # 110 + + log.mrent, + log.mscharge, + log.proplen, + log.value, + log.grant, + log.discount, + log.mortgageused, + log.mortgage, + log.mortgagelender, + log.mortgagelenderother, # 120 + + log.mortlen, + log.extrabor, + log.deposit, + log.mscharge, + log.value, + log.mortgageused, + log.mortgage, + log.mortlen, + log.extrabor, + log.deposit, # 130 + log.mscharge, + ] + end + private def default_2023_field_numbers @@ -225,4 +390,8 @@ private log.hhregres end end + + def default_2024_field_numbers + (1..131).to_a + end end