Module: Validations::Sales::SaleInformationValidations

Includes:
CollectionTimeHelper, MoneyFormattingHelper, Validations::SharedValidations
Included in:
SoftValidations
Defined in:
sales/sale_information_validations.rb

Instance Method Summary collapse

Instance Method Details

#check_non_staircasing_non_socialhomebuy_mortgage(record) ⇒ Object



178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
# File 'sales/sale_information_validations.rb', line 178

def check_non_staircasing_non_socialhomebuy_mortgage(record)
  if record.mortgage_used?
    return unless record.mortgage

    if over_tolerance?(record.mortgage_and_deposit_total, record.expected_shared_ownership_deposit_value, 1)
      %i[mortgage value deposit equity].each do |field|
        record.errors.add field, I18n.t("validations.sale_information.non_staircasing_mortgage.mortgage_used", mortgage_and_deposit_total: record.field_formatted_as_currency("mortgage_and_deposit_total"), expected_shared_ownership_deposit_value: record.field_formatted_as_currency("expected_shared_ownership_deposit_value"))
      end
      record.errors.add :type, :skip_bu_error, message: I18n.t("validations.sale_information.non_staircasing_mortgage.mortgage_used", mortgage_and_deposit_total: record.field_formatted_as_currency("mortgage_and_deposit_total"), expected_shared_ownership_deposit_value: record.field_formatted_as_currency("expected_shared_ownership_deposit_value"))
    end
  elsif record.mortgage_not_used?
    if over_tolerance?(record.deposit, record.expected_shared_ownership_deposit_value, 1)
      %i[mortgageused value deposit equity].each do |field|
        record.errors.add field, I18n.t("validations.sale_information.non_staircasing_mortgage.mortgage_not_used", deposit: record.field_formatted_as_currency("deposit"), expected_shared_ownership_deposit_value: record.field_formatted_as_currency("expected_shared_ownership_deposit_value"))
      end
      record.errors.add :type, :skip_bu_error, message: I18n.t("validations.sale_information.non_staircasing_mortgage.mortgage_not_used", deposit: record.field_formatted_as_currency("deposit"), expected_shared_ownership_deposit_value: record.field_formatted_as_currency("expected_shared_ownership_deposit_value"))
    end
  end
end

#check_non_staircasing_socialhomebuy_mortgage(record) ⇒ Object



156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
# File 'sales/sale_information_validations.rb', line 156

def check_non_staircasing_socialhomebuy_mortgage(record)
  return unless record.cashdis

  if record.mortgage_used?
    return unless record.mortgage

    if over_tolerance?(record.mortgage_deposit_and_discount_total, record.expected_shared_ownership_deposit_value, 1)
      %i[mortgage value deposit cashdis equity].each do |field|
        record.errors.add field, I18n.t("validations.sale_information.non_staircasing_mortgage.mortgage_used_socialhomebuy", mortgage_deposit_and_discount_total: record.field_formatted_as_currency("mortgage_deposit_and_discount_total"), expected_shared_ownership_deposit_value: record.field_formatted_as_currency("expected_shared_ownership_deposit_value"))
      end
      record.errors.add :type, :skip_bu_error, message: I18n.t("validations.sale_information.non_staircasing_mortgage.mortgage_used_socialhomebuy", mortgage_deposit_and_discount_total: record.field_formatted_as_currency("mortgage_deposit_and_discount_total"), expected_shared_ownership_deposit_value: record.field_formatted_as_currency("expected_shared_ownership_deposit_value"))
    end
  elsif record.mortgage_not_used?
    if over_tolerance?(record.deposit_and_discount_total, record.expected_shared_ownership_deposit_value, 1)
      %i[mortgageused value deposit cashdis equity].each do |field|
        record.errors.add field, I18n.t("validations.sale_information.non_staircasing_mortgage.mortgage_not_used_socialhomebuy", deposit_and_discount_total: record.field_formatted_as_currency("deposit_and_discount_total"), expected_shared_ownership_deposit_value: record.field_formatted_as_currency("expected_shared_ownership_deposit_value"))
      end
      record.errors.add :type, :skip_bu_error, message: I18n.t("validations.sale_information.non_staircasing_mortgage.mortgage_not_used_socialhomebuy", deposit_and_discount_total: record.field_formatted_as_currency("deposit_and_discount_total"), expected_shared_ownership_deposit_value: record.field_formatted_as_currency("expected_shared_ownership_deposit_value"))
    end
  end
end

#check_staircasing_non_socialhomebuy_mortgage(record) ⇒ Object



218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
# File 'sales/sale_information_validations.rb', line 218

def check_staircasing_non_socialhomebuy_mortgage(record)
  if record.mortgage_used?
    return unless record.mortgage

    if over_tolerance?(record.mortgage_and_deposit_total, record.stairbought_part_of_value, 1)
      %i[mortgage value deposit stairbought type].each do |field|
        record.errors.add field, I18n.t("validations.sale_information.staircasing_mortgage.mortgage_used", mortgage_and_deposit_total: record.field_formatted_as_currency("mortgage_and_deposit_total"), stairbought_part_of_value: record.field_formatted_as_currency("stairbought_part_of_value"))
      end
      record.errors.add :type, :skip_bu_error, message: I18n.t("validations.sale_information.staircasing_mortgage.mortgage_used", mortgage_and_deposit_total: record.field_formatted_as_currency("mortgage_and_deposit_total"), stairbought_part_of_value: record.field_formatted_as_currency("stairbought_part_of_value"))
    end
  elsif over_tolerance?(record.deposit, record.stairbought_part_of_value, 1)
    %i[mortgageused value deposit stairbought type].each do |field|
      record.errors.add field, I18n.t("validations.sale_information.staircasing_mortgage.mortgage_not_used", deposit: record.field_formatted_as_currency("deposit"), stairbought_part_of_value: record.field_formatted_as_currency("stairbought_part_of_value"))
    end
    record.errors.add :type, :skip_bu_error, message: I18n.t("validations.sale_information.staircasing_mortgage.mortgage_not_used", deposit: record.field_formatted_as_currency("deposit"), stairbought_part_of_value: record.field_formatted_as_currency("stairbought_part_of_value"))
  end
end

#check_staircasing_socialhomebuy_mortgage(record) ⇒ Object



198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
# File 'sales/sale_information_validations.rb', line 198

def check_staircasing_socialhomebuy_mortgage(record)
  return unless record.cashdis

  if record.mortgage_used?
    return unless record.mortgage

    if over_tolerance?(record.mortgage_deposit_and_discount_total, record.stairbought_part_of_value, 1)
      %i[mortgage value deposit cashdis stairbought].each do |field|
        record.errors.add field, I18n.t("validations.sale_information.staircasing_mortgage.mortgage_used_socialhomebuy", mortgage_deposit_and_discount_total: record.field_formatted_as_currency("mortgage_deposit_and_discount_total"), stairbought_part_of_value: record.field_formatted_as_currency("stairbought_part_of_value"))
      end
      record.errors.add :type, :skip_bu_error, message: I18n.t("validations.sale_information.staircasing_mortgage.mortgage_used_socialhomebuy", mortgage_deposit_and_discount_total: record.field_formatted_as_currency("mortgage_deposit_and_discount_total"), stairbought_part_of_value: record.field_formatted_as_currency("stairbought_part_of_value"))
    end
  elsif over_tolerance?(record.deposit_and_discount_total, record.stairbought_part_of_value, 1)
    %i[mortgageused value deposit cashdis stairbought].each do |field|
      record.errors.add field, I18n.t("validations.sale_information.staircasing_mortgage.mortgage_not_used_socialhomebuy", deposit_and_discount_total: record.field_formatted_as_currency("deposit_and_discount_total"), stairbought_part_of_value: record.field_formatted_as_currency("stairbought_part_of_value"))
    end
    record.errors.add :type, :skip_bu_error, message: I18n.t("validations.sale_information.staircasing_mortgage.mortgage_not_used_socialhomebuy", deposit_and_discount_total: record.field_formatted_as_currency("deposit_and_discount_total"), stairbought_part_of_value: record.field_formatted_as_currency("stairbought_part_of_value"))
  end
end

#over_tolerance?(expected, actual, tolerance) ⇒ Boolean

Returns:

  • (Boolean)


250
251
252
# File 'sales/sale_information_validations.rb', line 250

def over_tolerance?(expected, actual, tolerance)
  (expected - actual).abs >= tolerance
end

#validate_basic_monthly_rent(record) ⇒ Object



71
72
73
74
75
76
77
78
# File 'sales/sale_information_validations.rb', line 71

def validate_basic_monthly_rent(record)
  return unless record.mrent && record.ownershipsch && record.type

  if record.shared_ownership_scheme? && !record.old_persons_shared_ownership? && record.mrent > 9999
    record.errors.add :mrent, I18n.t("validations.sale_information.monthly_rent.higher_than_expected")
    record.errors.add :type, I18n.t("validations.sale_information.monthly_rent.higher_than_expected")
  end
end

#validate_discount_and_value(record) ⇒ Object



108
109
110
111
112
113
114
115
116
117
118
119
120
121
# File 'sales/sale_information_validations.rb', line 108

def validate_discount_and_value(record)
  return unless record.saledate && record.form.start_year_after_2024?
  return unless record.discount && record.value && record.la

  if record.london_property? && record.discount_value > 136_400
    %i[discount value la postcode_full uprn].each do |field|
      record.errors.add field, I18n.t("validations.sale_information.value.over_discounted_london_max", discount_value: record.field_formatted_as_currency("discount_value"))
    end
  elsif record.property_not_in_london? && record.discount_value > 102_400
    %i[discount value la postcode_full uprn].each do |field|
      record.errors.add field, I18n.t("validations.sale_information.value.over_discounted_max", discount_value: record.field_formatted_as_currency("discount_value"))
    end
  end
end

#validate_discounted_ownership_value(record) ⇒ Object



44
45
46
47
48
49
50
51
52
53
54
55
# File 'sales/sale_information_validations.rb', line 44

def validate_discounted_ownership_value(record)
  return unless record.saledate && record.form.start_year_after_2024?
  return unless record.value && record.deposit && record.ownershipsch
  return unless record.mortgage || record.mortgageused == 2 || record.mortgageused == 3
  return unless record.discount || record.grant || record.type == 29

  if over_tolerance?(record.mortgage_deposit_and_grant_total, record.value_with_discount, 1) && record.discounted_ownership_sale?
    %i[mortgageused mortgage value deposit ownershipsch discount grant].each do |field|
      record.errors.add field, I18n.t("validations.sale_information.discounted_ownership_value", mortgage_deposit_and_grant_total: record.field_formatted_as_currency("mortgage_deposit_and_grant_total"), value_with_discount: record.field_formatted_as_currency("value_with_discount"))
    end
  end
end

#validate_exchange_date(record) ⇒ Object



21
22
23
24
25
26
27
28
29
30
31
32
33
# File 'sales/sale_information_validations.rb', line 21

def validate_exchange_date(record)
  return unless record.exdate && record.saledate

  if record.exdate > record.saledate
    record.errors.add :exdate, I18n.t("validations.sale_information.exdate.must_be_before_saledate")
    record.errors.add :saledate, I18n.t("validations.sale_information.saledate.must_be_after_exdate")
  end

  if record.saledate - record.exdate >= 1.year
    record.errors.add :exdate, I18n.t("validations.sale_information.exdate.must_be_less_than_1_year_from_saledate")
    record.errors.add :saledate, I18n.t("validations.sale_information.saledate.must_be_less_than_1_year_from_exdate")
  end
end

#validate_grant_amount(record) ⇒ Object



80
81
82
83
84
85
86
87
# File 'sales/sale_information_validations.rb', line 80

def validate_grant_amount(record)
  return unless record.saledate && record.form.start_year_after_2024?
  return unless record.grant && (record.type == 8 || record.type == 21)

  unless record.grant.between?(9_000, 16_000)
    record.errors.add :grant, I18n.t("validations.sale_information.grant.out_of_range")
  end
end

#validate_mortgage_used_and_stairbought(record) ⇒ Object



147
148
149
150
151
152
153
154
# File 'sales/sale_information_validations.rb', line 147

def validate_mortgage_used_and_stairbought(record)
  return unless record.stairowned && record.mortgageused

  if !record.stairowned_100? && record.mortgageused == 3
    record.errors.add :stairowned, I18n.t("validations.sale_information.stairowned.mortgageused_dont_know")
    record.errors.add :mortgageused, I18n.t("validations.sale_information.stairowned.mortgageused_dont_know")
  end
end

#validate_mortgage_used_dont_know(record) ⇒ Object



236
237
238
239
240
241
242
243
244
245
246
247
248
# File 'sales/sale_information_validations.rb', line 236

def validate_mortgage_used_dont_know(record)
  return unless record.mortgageused == 3

  if record.discounted_ownership_sale?
    record.errors.add(:mortgageused, I18n.t("validations.invalid_option", question: "Was a mortgage used for the purchase of this property?"))
  end
  if record.outright_sale? && record.saledate && !record.form.start_year_after_2024?
    record.errors.add(:mortgageused, I18n.t("validations.invalid_option", question: "Was a mortgage used for the purchase of this property?"))
  end
  if record.shared_ownership_scheme? && record.staircase && record.staircase != 1
    record.errors.add(:mortgageused, I18n.t("validations.invalid_option", question: "Was a mortgage used for the purchase of this property?"))
  end
end

#validate_non_staircasing_mortgage(record) ⇒ Object



123
124
125
126
127
128
129
130
131
132
133
# File 'sales/sale_information_validations.rb', line 123

def validate_non_staircasing_mortgage(record)
  return unless record.saledate && record.form.start_year_after_2024?
  return unless record.value && record.deposit && record.equity
  return unless record.shared_ownership_scheme? && record.type && record.mortgageused && record.is_not_staircasing?

  if record.social_homebuy?
    check_non_staircasing_socialhomebuy_mortgage(record)
  else
    check_non_staircasing_non_socialhomebuy_mortgage(record)
  end
end

#validate_outright_sale_value_matches_mortgage_plus_deposit(record) ⇒ Object



57
58
59
60
61
62
63
64
65
66
67
68
69
# File 'sales/sale_information_validations.rb', line 57

def validate_outright_sale_value_matches_mortgage_plus_deposit(record)
  return unless record.saledate && record.form.start_year_after_2024?
  return unless record.outright_sale?
  return unless record.mortgage_used? && record.mortgage
  return unless record.deposit && record.value

  if over_tolerance?(record.mortgage_and_deposit_total, record.value, 1)
    %i[mortgageused mortgage value deposit].each do |field|
      record.errors.add field, I18n.t("validations.sale_information.outright_sale_value", mortgage_and_deposit_total: record.field_formatted_as_currency("mortgage_and_deposit_total"), value: record.field_formatted_as_currency("value"))
    end
    record.errors.add :ownershipsch, :skip_bu_error, message: I18n.t("validations.sale_information.outright_sale_value", mortgage_and_deposit_total: record.field_formatted_as_currency("mortgage_and_deposit_total"), value: record.field_formatted_as_currency("value"))
  end
end

#validate_practical_completion_date(record) ⇒ Object



6
7
8
9
10
11
12
13
14
15
16
17
18
19
# File 'sales/sale_information_validations.rb', line 6

def validate_practical_completion_date(record)
  return unless record.hodate.present? && date_valid?("hodate", record)
  return if record.saledate.blank?

  if record.hodate > record.saledate
    record.errors.add :hodate, I18n.t("validations.sale_information.hodate.must_be_before_saledate")
    record.errors.add :saledate, I18n.t("validations.sale_information.saledate.must_be_after_hodate")
  end

  if record.saledate - record.hodate >= 3.years && record.form.start_year_after_2024?
    record.errors.add :hodate, I18n.t("validations.sale_information.hodate.must_be_less_than_3_years_from_saledate")
    record.errors.add :saledate, I18n.t("validations.sale_information.saledate.must_be_less_than_3_years_from_hodate")
  end
end

#validate_previous_property_unit_type(record) ⇒ Object



35
36
37
38
39
40
41
42
# File 'sales/sale_information_validations.rb', line 35

def validate_previous_property_unit_type(record)
  return unless record.fromprop && record.frombeds

  if record.frombeds != 1 && record.fromprop == 2
    record.errors.add :frombeds, I18n.t("validations.sale_information.previous_property_type.property_type_bedsit")
    record.errors.add :fromprop, I18n.t("validations.sale_information.previous_property_type.property_type_bedsit")
  end
end

#validate_stairbought(record) ⇒ Object



89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
# File 'sales/sale_information_validations.rb', line 89

def validate_stairbought(record)
  return unless record.stairbought && record.type
  return unless record.saledate && record.form.start_year_after_2024?

  max_stairbought = case record.type
                    when 30, 16, 28, 31, 32
                      90
                    when 2, 18
                      75
                    when 24
                      50
                    end

  if max_stairbought && record.stairbought > max_stairbought
    record.errors.add :stairbought, I18n.t("validations.sale_information.stairbought.over_max", max_stairbought:, type: record.form.get_question("type", record).answer_label(record))
    record.errors.add :type, I18n.t("validations.sale_information.stairbought.over_max", max_stairbought:, type: record.form.get_question("type", record).answer_label(record))
  end
end

#validate_staircasing_mortgage(record) ⇒ Object



135
136
137
138
139
140
141
142
143
144
145
# File 'sales/sale_information_validations.rb', line 135

def validate_staircasing_mortgage(record)
  return unless record.saledate && record.form.start_year_after_2024?
  return unless record.value && record.deposit && record.stairbought
  return unless record.shared_ownership_scheme? && record.type && record.mortgageused && record.is_staircase?

  if record.social_homebuy?
    check_staircasing_socialhomebuy_mortgage(record)
  else
    check_staircasing_non_socialhomebuy_mortgage(record)
  end
end