diff --git a/app/services/bulk_upload/sales/year2022/row_parser.rb b/app/services/bulk_upload/sales/year2022/row_parser.rb index cba51ba46..ec3f5e085 100644 --- a/app/services/bulk_upload/sales/year2022/row_parser.rb +++ b/app/services/bulk_upload/sales/year2022/row_parser.rb @@ -259,12 +259,22 @@ class BulkUpload::Sales::Year2022::RowParser attribute :field_124, :integer attribute :field_125, :integer - # validates :field_1, presence: true, numericality: { in: (1..12) } - # validates :field_4, numericality: { in: (1..999), allow_blank: true } - # validates :field_4, presence: true, if: :field_4_presence_check + validates :field_2, presence: { message: I18n.t("validations.not_answered", question: "sale completion date (day)") } + validates :field_3, presence: { message: I18n.t("validations.not_answered", question: "sale completion date (month)") } + validates :field_4, presence: { message: I18n.t("validations.not_answered", question: "sale completion date (year)") } + validates :field_4, format: { with: /\A\d{2}\z/, message: I18n.t("validations.setup.saledate.year_not_two_digits") } + + validates :field_113, presence: { message: I18n.t("validations.not_answered", question: "ownership type") } + validates :field_57, presence: { message: I18n.t("validations.not_answered", question: "shared ownership type") }, if: :shared_ownership? + validates :field_76, presence: { message: I18n.t("validations.not_answered", question: "shared ownership type") }, if: :discounted_ownership? + validates :field_84, presence: { message: I18n.t("validations.not_answered", question: "shared ownership type") }, if: :outright_sale? + validates :field_115, presence: { message: I18n.t("validations.not_answered", question: "will the buyers live in the property") }, if: :outright_sale? + validates :field_116, presence: { message: I18n.t("validations.not_answered", question: "joint purchase") }, if: :joint_purchase_asked? + validates :field_114, presence: { message: I18n.t("validations.not_answered", question: "company buyer") }, if: :outright_sale? + validates :field_109, presence: { message: I18n.t("validations.not_answered", question: "more than 2 buyers") }, if: :joint_purchase? - # delegate :valid?, to: :native_object - # delegate :errors, to: :native_object + validate :validate_nulls + validate :validate_valid_radio_option validate :validate_owning_org_data_given validate :validate_owning_org_exists @@ -272,9 +282,7 @@ class BulkUpload::Sales::Year2022::RowParser validate :validate_created_by_exists validate :validate_created_by_related - - validate :validate_nulls - validate :validate_valid_radio_option + validate :validate_relevant_collection_window def self.question_for_field(field) QUESTIONS[field] @@ -325,6 +333,26 @@ class BulkUpload::Sales::Year2022::RowParser private + def shared_ownership? + field_113 == 1 + end + + def discounted_ownership? + field_113 == 2 + end + + def outright_sale? + field_113 == 3 + end + + def joint_purchase? + field_116 == 1 + end + + def joint_purchase_asked? + shared_ownership? || discounted_ownership? || field_114 == 2 + end + def field_mapping_for_errors { purchid: %i[field_1], @@ -679,90 +707,68 @@ private end def sale_type - case field_113 - when 1 then field_57 - when 2 then field_76 - when 3 then field_84 - end + return field_57 if shared_ownership? + return field_76 if discounted_ownership? + return field_84 if outright_sale? end def value - case field_113 - when 1 then field_68 - when 2 then field_77 - when 3 then field_87 - end + return field_68 if shared_ownership? + return field_77 if discounted_ownership? + return field_87 if outright_sale? end def mortgage - case field_113 - when 1 then field_70 - when 2 then field_80 - when 3 then field_88 - end + return field_70 if shared_ownership? + return field_80 if discounted_ownership? + return field_88 if outright_sale? end def extrabor - case field_113 - when 1 then field_71 - when 2 then field_81 - when 3 then field_89 - end + return field_71 if shared_ownership? + return field_81 if discounted_ownership? + return field_89 if outright_sale? end def deposit - case field_113 - when 1 then field_72 - when 2 then field_82 - when 3 then field_90 - end + return field_72 if shared_ownership? + return field_82 if discounted_ownership? + return field_90 if outright_sale? end def mscharge - case field_113 - when 1 then field_75 - when 2 then field_83 - when 3 then field_91 - end + return field_75 if shared_ownership? + return field_83 if discounted_ownership? + return field_91 if outright_sale? end def mortgagelender - case field_113 - when 1 then field_98 - when 2 then field_100 - when 3 then field_102 - end + return field_98 if shared_ownership? + return field_100 if discounted_ownership? + return field_102 if outright_sale? end def mortgagelenderother - case field_113 - when 1 then field_99 - when 2 then field_101 - when 3 then field_103 - end + return field_99 if shared_ownership? + return field_101 if discounted_ownership? + return field_103 if outright_sale? end def mortlen - case field_113 - when 1 then field_105 - when 2 then field_106 - when 3 then field_107 - end + return field_105 if shared_ownership? + return field_106 if discounted_ownership? + return field_107 if outright_sale? end def proplen - case field_113 - when 1 then field_110 - when 2 then field_108 - end + return field_110 if shared_ownership? + return field_108 if discounted_ownership? end def mortgageused - case field_113 - when 1 then field_123 - when 2 then field_124 - when 3 then field_125 - end + return field_123 if shared_ownership? + return field_124 if discounted_ownership? + return field_125 if outright_sale? end def owning_organisation @@ -914,4 +920,14 @@ private end end end + + def validate_relevant_collection_window + return if saledate.blank? || bulk_upload.form.blank? + + unless bulk_upload.form.valid_start_date_for_form?(saledate) + errors.add(:field_2, I18n.t("validations.date.outside_collection_window")) + errors.add(:field_3, I18n.t("validations.date.outside_collection_window")) + errors.add(:field_4, I18n.t("validations.date.outside_collection_window")) + end + end end diff --git a/config/locales/en.yml b/config/locales/en.yml index 34dc4651e..04a9b2e00 100644 --- a/config/locales/en.yml +++ b/config/locales/en.yml @@ -198,6 +198,8 @@ en: lettype: general_needs_mismatch: Lettings type must be a general needs type because you selected general needs when uploading the file supported_housing_mismatch: Lettings type must be a supported housing type because you selected supported housing when uploading the file + saledate: + year_not_two_digits: "Sale completion year must be 2 digits" property: uprn: diff --git a/spec/services/bulk_upload/sales/year2022/row_parser_spec.rb b/spec/services/bulk_upload/sales/year2022/row_parser_spec.rb index 12c3ea7d5..bd5520ea7 100644 --- a/spec/services/bulk_upload/sales/year2022/row_parser_spec.rb +++ b/spec/services/bulk_upload/sales/year2022/row_parser_spec.rb @@ -14,15 +14,16 @@ RSpec.describe BulkUpload::Sales::Year2022::RowParser do let(:setup_section_params) do { bulk_upload:, - field_1: "test id", - field_92: owning_org.old_visible_id, - field_2: now.day.to_s, - field_3: now.month.to_s, - field_4: now.strftime("%g"), - field_113: "1", - field_57: "2", - field_116: "2", - field_115: "1", + field_1: "test id", # purchase id + field_92: owning_org.old_visible_id, # organisation + field_93: user.email, # user + field_2: now.day.to_s, # sale day + field_3: now.month.to_s, # sale month + field_4: now.strftime("%g"), # sale year + field_113: "1", # owhershipsch + field_57: "2", # shared ownership sale type + field_116: "2", # joint purchase + field_115: "1", # will the buyers live in the property } end @@ -175,13 +176,120 @@ RSpec.describe BulkUpload::Sales::Year2022::RowParser do end end - context "when setup section not complete" do - let(:attributes) { { bulk_upload:, field_113: "" } } + context "when setup section not complete and type is not given" do + let(:attributes) do + { + bulk_upload:, + field_1: "test id", + } + end + + it "has errors on correct setup fields" do + errors = parser.errors.select { |e| e.options[:category] == :setup }.map(&:attribute) + + expect(errors).to eql(%i[field_2 field_3 field_4 field_113 field_92]) + end + end + + context "when setup section not complete and type is shared ownership" do + let(:attributes) do + { + bulk_upload:, + field_1: "test id", + field_113: "1", + } + end + + it "has errors on correct setup fields" do + errors = parser.errors.select { |e| e.options[:category] == :setup }.map(&:attribute) + + expect(errors).to eql(%i[field_2 field_3 field_4 field_57 field_116 field_92]) + end + end + + context "when setup section not complete it's shared ownership joint purchase" do + let(:attributes) do + { + bulk_upload:, + field_1: "test id", + field_113: "1", + field_57: "2", + field_116: "1", + } + end + + it "has errors on correct setup fields" do + errors = parser.errors.select { |e| e.options[:category] == :setup }.map(&:attribute) + + expect(errors).to eql(%i[field_2 field_3 field_4 field_109 field_92]) + end + end + + context "when setup section not complete and type is discounted ownership" do + let(:attributes) do + { + bulk_upload:, + field_1: "test id", + field_113: "2", + } + end + + it "has errors on correct setup fields" do + errors = parser.errors.select { |e| e.options[:category] == :setup }.map(&:attribute) + + expect(errors).to eql(%i[field_2 field_3 field_4 field_76 field_116 field_92]) + end + end + + context "when setup section not complete it's discounted ownership joint purchase" do + let(:attributes) do + { + bulk_upload:, + field_1: "test id", + field_113: "2", + field_76: "8", + field_116: "1", + } + end + + it "has errors on correct setup fields" do + errors = parser.errors.select { |e| e.options[:category] == :setup }.map(&:attribute) + + expect(errors).to eql(%i[field_2 field_3 field_4 field_109 field_92]) + end + end + + context "when setup section not complete and type is outright sale" do + let(:attributes) do + { + bulk_upload:, + field_1: "test id", + field_113: "3", + } + end + + it "has errors on correct setup fields" do + errors = parser.errors.select { |e| e.options[:category] == :setup }.map(&:attribute) + + expect(errors).to eql(%i[field_2 field_3 field_4 field_84 field_114 field_92]) + end + end + + context "when setup section not complete outright sale buyer is not company" do + let(:attributes) do + { + bulk_upload:, + field_1: "test id", + field_113: "3", + field_84: "12", + field_114: "2", + } + end - it "has errors on setup fields" do + it "has errors on correct setup fields" do errors = parser.errors.select { |e| e.options[:category] == :setup }.map(&:attribute) - expect(errors).to eql(%i[field_1 field_92 field_2 field_3 field_4 field_134 field_113 field_57 field_116 field_115]) + expect(errors).to eql(%i[field_2 field_3 field_4 field_115 field_116 field_92]) end end @@ -332,14 +440,85 @@ RSpec.describe BulkUpload::Sales::Year2022::RowParser do end end - xdescribe "#field_117" do + describe "#field_117" do context "when not a possible value" do - let(:attributes) { { bulk_upload:, field_117: "3" } } + let(:attributes) { valid_attributes.merge({ field_117: "3" }) } it "is not valid" do expect(parser.errors).to include(:field_117) end end end + + describe "fields 2, 3, 4 => saledate" do + context "when all of these fields are blank" do + let(:attributes) { setup_section_params.merge({ field_2: nil, field_3: nil, field_4: nil }) } + + it "returns them as setup errors" do + setup_errors = parser.errors.select { |e| e.options[:category] == :setup } + + expect(setup_errors.find { |e| e.attribute == :field_2 }).to be_present + expect(setup_errors.find { |e| e.attribute == :field_3 }).to be_present + expect(setup_errors.find { |e| e.attribute == :field_4 }).to be_present + end + end + + context "when one of these fields is blank" do + let(:attributes) { setup_section_params.merge({ field_2: "1", field_3: "1", field_4: nil }) } + + it "returns an error only on blank field" do + expect(parser.errors[:field_2]).to be_blank + expect(parser.errors[:field_3]).to be_blank + expect(parser.errors[:field_4]).to be_present + end + end + + context "when field 4 is 4 digits instead of 2" do + let(:attributes) { setup_section_params.merge({ bulk_upload:, field_4: "2022" }) } + + it "returns an error" do + expect(parser.errors[:field_4]).to include("Sale completion year must be 2 digits") + end + end + + context "when invalid date given" do + let(:attributes) { setup_section_params.merge({ field_2: "a", field_3: "12", field_4: "2022" }) } + + it "does not raise an error" do + expect { parser.valid? }.not_to raise_error + end + end + + context "when inside of collection year" do + let(:attributes) { setup_section_params.merge({ field_2: "1", field_3: "10", field_4: "22" }) } + + let(:bulk_upload) { create(:bulk_upload, :sales, user:, year: 2022) } + + it "does not return errors" do + expect(parser.errors[:field_2]).not_to be_present + expect(parser.errors[:field_3]).not_to be_present + expect(parser.errors[:field_4]).not_to be_present + end + end + + context "when outside of collection year" do + around do |example| + Timecop.freeze(Date.new(2022, 4, 2)) do + example.run + end + Timecop.return + end + + let(:attributes) { setup_section_params.merge({ field_2: "1", field_3: "1", field_4: "22" }) } + + let(:bulk_upload) { create(:bulk_upload, :sales, user:, year: 2022) } + + it "returns errors" do + expect(parser.errors[:field_2]).to be_present + expect(parser.errors[:field_3]).to be_present + expect(parser.errors[:field_4]).to be_present + end + end + end end end