Browse Source

Merge branch 'main' into CLDC-3638-add-custom-resource

pull/2690/head
kosiakkatrina 2 years ago committed by GitHub
parent
commit
e89ee8fc80
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
  1. 14
      app/components/bulk_upload_error_row_component.html.erb
  2. 13
      app/components/bulk_upload_error_row_component.rb
  3. 5
      app/frontend/styles/_bulk-uploads.scss
  4. 1
      app/models/form/sales/pages/buyer1_income.rb
  5. 3
      app/models/form/sales/pages/buyer1_income_max_value_check.rb
  6. 5
      app/models/form/sales/pages/buyer1_income_min_value_check.rb
  7. 1
      app/models/form/sales/pages/buyer2_income.rb
  8. 3
      app/models/form/sales/pages/buyer2_income_max_value_check.rb
  9. 5
      app/models/form/sales/pages/buyer2_income_min_value_check.rb
  10. 3
      app/models/form/sales/pages/combined_income_max_value_check.rb
  11. 5
      app/models/form/sales/pages/deposit_value_check.rb
  12. 1
      app/models/form/sales/pages/housing_benefits.rb
  13. 6
      app/models/form/sales/pages/mortgage_value_check.rb
  14. 1
      app/models/form/sales/pages/previous_ownership.rb
  15. 1
      app/models/form/sales/pages/savings.rb
  16. 5
      app/models/form/sales/pages/savings_value_check.rb
  17. 4
      app/models/form/sales/questions/buyer1_income.rb
  18. 3
      app/models/form/sales/questions/buyer1_income_known.rb
  19. 3
      app/models/form/sales/questions/buyer1_income_value_check.rb
  20. 2
      app/models/form/sales/questions/buyer1_mortgage.rb
  21. 4
      app/models/form/sales/questions/buyer2_income.rb
  22. 3
      app/models/form/sales/questions/buyer2_income_known.rb
  23. 3
      app/models/form/sales/questions/buyer2_income_value_check.rb
  24. 2
      app/models/form/sales/questions/buyer2_mortgage.rb
  25. 3
      app/models/form/sales/questions/combined_income_value_check.rb
  26. 3
      app/models/form/sales/questions/deposit_value_check.rb
  27. 3
      app/models/form/sales/questions/housing_benefits.rb
  28. 3
      app/models/form/sales/questions/mortgage_value_check.rb
  29. 3
      app/models/form/sales/questions/prevown.rb
  30. 3
      app/models/form/sales/questions/prevshared.rb
  31. 3
      app/models/form/sales/questions/savings.rb
  32. 3
      app/models/form/sales/questions/savings_nk.rb
  33. 3
      app/models/form/sales/questions/savings_value_check.rb
  34. 2
      app/models/form/sales/questions/uprn.rb
  35. 2
      app/models/form/sales/questions/uprn_known.rb
  36. 48
      app/models/validations/sales/household_validations.rb
  37. 15
      app/models/validations/sales/property_validations.rb
  38. 4
      app/models/validations/shared_validations.rb
  39. 12
      app/services/bulk_upload/sales/year2024/row_parser.rb
  40. 43
      config/locales/en.yml
  41. 90
      config/locales/forms/2023/sales/income_benefits_and_savings.en.yml
  42. 60
      config/locales/forms/2023/sales/soft_validations.en.yml
  43. 90
      config/locales/forms/2024/sales/income_benefits_and_savings.en.yml
  44. 60
      config/locales/forms/2024/sales/soft_validations.en.yml
  45. 47
      config/locales/validations/sales/household.en.yml
  46. 27
      config/locales/validations/sales/property_information.en.yml
  47. 3
      spec/models/form/sales/pages/buyer1_income_max_value_check_spec.rb
  48. 3
      spec/models/form/sales/pages/buyer1_income_min_value_check_spec.rb
  49. 3
      spec/models/form/sales/pages/buyer2_income_max_value_check_spec.rb
  50. 3
      spec/models/form/sales/pages/buyer2_income_min_value_check_spec.rb
  51. 3
      spec/models/form/sales/pages/combined_income_max_value_check_spec.rb
  52. 3
      spec/models/form/sales/pages/deposit_value_check_spec.rb
  53. 3
      spec/models/form/sales/pages/mortgage_value_check_spec.rb
  54. 3
      spec/models/form/sales/pages/savings_value_check_spec.rb
  55. 3
      spec/models/form/sales/subsections/discounted_ownership_scheme_spec.rb
  56. 2
      spec/models/form/sales/subsections/shared_ownership_scheme_spec.rb
  57. 50
      spec/models/validations/sales/household_validations_spec.rb

14
app/components/bulk_upload_error_row_component.html.erb

@ -13,7 +13,7 @@
<% if critical_errors.any? %> <% if critical_errors.any? %>
<h2 class="govuk-heading-m">Critical errors</h2> <h2 class="govuk-heading-m">Critical errors</h2>
<p class="govuk-body">These errors must be fixed to complete your logs.</p> <p class="govuk-body">These errors must be fixed to complete your logs.</p>
<%= govuk_table do |table| %> <%= govuk_table(html_attributes: { class: potential_errors.any? ? "" : "no-bottom-border" }) do |table| %>
<%= table.with_head do |head| %> <%= table.with_head do |head| %>
<% head.with_row do |row| %> <% head.with_row do |row| %>
<% row.with_cell(header: true, text: "Cell") %> <% row.with_cell(header: true, text: "Cell") %>
@ -39,7 +39,7 @@
<% if potential_errors.any? %> <% if potential_errors.any? %>
<h2 class="govuk-heading-m">Potential errors</h2> <h2 class="govuk-heading-m">Potential errors</h2>
<p class="govuk-body">The following groups of cells might have conflicting data. Check the answers and fix any incorrect data.<br><br>If the answers are correct, fix the critical errors and reupload the file. You'll need to confirm that the following data is correct when the file only contains potential errors.</p> <p class="govuk-body">The following groups of cells might have conflicting data. Check the answers and fix any incorrect data.<br><br>If the answers are correct, fix the critical errors and reupload the file. You'll need to confirm that the following data is correct when the file only contains potential errors.</p>
<%= govuk_table do |table| %> <%= govuk_table(html_attributes: { class: "no-bottom-border" }) do |table| %>
<%= table.with_head do |head| %> <%= table.with_head do |head| %>
<% head.with_row do |row| %> <% head.with_row do |row| %>
<% row.with_cell(header: true, text: "Cell") %> <% row.with_cell(header: true, text: "Cell") %>
@ -50,16 +50,16 @@
<% end %> <% end %>
<%= table.with_body do |body| %> <%= table.with_body do |body| %>
<% potential_errors.group_by(&:error).each do |error_message, errors| %> <% potential_errors.group_by(&:error).each_with_index do |(error_message, errors), group_index| %>
<% total_groups = potential_errors.group_by(&:error).size %>
<% errors.each_with_index do |error, index| %> <% errors.each_with_index do |error, index| %>
<% row_class = "grouped-rows" %> <% row_class = row_classes(index, errors.size) %>
<% row_class += " first-row" if index.zero? %>
<% row_class += " last-row" if index == errors.size - 1 %>
<% body.with_row(html_attributes: { class: row_class }) do |row| %> <% body.with_row(html_attributes: { class: row_class }) do |row| %>
<% row.with_cell(text: error.cell) %> <% row.with_cell(text: error.cell) %>
<% row.with_cell(text: question_for_field(error.field), html_attributes: { class: "govuk-!-width-one-half" }) %> <% row.with_cell(text: question_for_field(error.field), html_attributes: { class: "govuk-!-width-one-half" }) %>
<% if index == 0 %> <% if index == 0 %>
<% row.with_cell(text: error_message.html_safe, rowspan: errors.size, html_attributes: { class: "govuk-!-font-weight-bold govuk-!-width-one-half grouped-multirow-cell" }) %> <% cell_class = cell_classes(group_index, total_groups) %>
<% row.with_cell(text: error_message.html_safe, rowspan: errors.size, html_attributes: { class: cell_class }) %>
<% end %> <% end %>
<% row.with_cell(text: error.field.humanize) %> <% row.with_cell(text: error.field.humanize) %>
<% end %> <% end %>

13
app/components/bulk_upload_error_row_component.rb

@ -62,4 +62,17 @@ class BulkUploadErrorRowComponent < ViewComponent::Base
def sales? def sales?
bulk_upload.log_type == "sales" bulk_upload.log_type == "sales"
end end
def row_classes(index, errors_size)
row_class = "grouped-rows"
row_class += " first-row" if index.zero?
row_class += " last-row" if index == errors_size - 1
row_class
end
def cell_classes(group_index, total_groups)
cell_class = "govuk-!-font-weight-bold govuk-!-width-one-half"
cell_class += " grouped-multirow-cell" unless group_index == total_groups - 1
cell_class
end
end end

5
app/frontend/styles/_bulk-uploads.scss

@ -12,6 +12,11 @@
border-bottom: 1px solid #b1b4b6; border-bottom: 1px solid #b1b4b6;
} }
.no-bottom-border,
.no-bottom-border > tbody > tr:last-of-type td {
border-bottom: none;
}
.text-normal-break { .text-normal-break {
white-space: normal; white-space: normal;
word-break: break-all; word-break: break-all;

1
app/models/form/sales/pages/buyer1_income.rb

@ -2,6 +2,7 @@ class Form::Sales::Pages::Buyer1Income < ::Form::Page
def initialize(id, hsh, subsection) def initialize(id, hsh, subsection)
super super
@id = "buyer_1_income" @id = "buyer_1_income"
@copy_key = "sales.income_benefits_and_savings.buyer_1_income"
end end
def questions def questions

3
app/models/form/sales/pages/buyer1_income_max_value_check.rb

@ -6,8 +6,9 @@ class Form::Sales::Pages::Buyer1IncomeMaxValueCheck < ::Form::Page
"income1_over_soft_max?" => true, "income1_over_soft_max?" => true,
}, },
] ]
@copy_key = "sales.soft_validations.income1_value_check.max"
@title_text = { @title_text = {
"translation" => "soft_validations.income.over_soft_max_for_la_buyer_1", "translation" => "forms.#{form.start_date.year}.#{@copy_key}.title_text",
"arguments" => [ "arguments" => [
{ {
"key" => "field_formatted_as_currency", "key" => "field_formatted_as_currency",

5
app/models/form/sales/pages/buyer1_income_min_value_check.rb

@ -6,8 +6,9 @@ class Form::Sales::Pages::Buyer1IncomeMinValueCheck < ::Form::Page
"income1_under_soft_min?" => true, "income1_under_soft_min?" => true,
}, },
] ]
@copy_key = "sales.soft_validations.income1_value_check.min"
@title_text = { @title_text = {
"translation" => "soft_validations.income.under_soft_min_for_economic_status.title_text", "translation" => "forms.#{form.start_date.year}.#{@copy_key}.title_text",
"arguments" => [ "arguments" => [
{ {
"key" => "field_formatted_as_currency", "key" => "field_formatted_as_currency",
@ -22,7 +23,7 @@ class Form::Sales::Pages::Buyer1IncomeMinValueCheck < ::Form::Page
], ],
} }
@informative_text = { @informative_text = {
"translation" => "soft_validations.income.under_soft_min_for_economic_status.hint_text", "translation" => "forms.#{form.start_date.year}.#{@copy_key}.informative_text",
"arguments" => [], "arguments" => [],
} }
end end

1
app/models/form/sales/pages/buyer2_income.rb

@ -2,6 +2,7 @@ class Form::Sales::Pages::Buyer2Income < ::Form::Page
def initialize(id, hsh, subsection) def initialize(id, hsh, subsection)
super super
@id = "buyer_2_income" @id = "buyer_2_income"
@copy_key = "sales.income_benefits_and_savings.buyer_2_income"
@depends_on = [{ @depends_on = [{
"joint_purchase?" => true, "joint_purchase?" => true,
}] }]

3
app/models/form/sales/pages/buyer2_income_max_value_check.rb

@ -6,8 +6,9 @@ class Form::Sales::Pages::Buyer2IncomeMaxValueCheck < ::Form::Page
"income2_over_soft_max?" => true, "income2_over_soft_max?" => true,
}, },
] ]
@copy_key = "sales.soft_validations.income2_value_check.max"
@title_text = { @title_text = {
"translation" => "soft_validations.income.over_soft_max_for_la_buyer_2", "translation" => "forms.#{form.start_date.year}.#{@copy_key}.title_text",
"arguments" => [ "arguments" => [
{ {
"key" => "field_formatted_as_currency", "key" => "field_formatted_as_currency",

5
app/models/form/sales/pages/buyer2_income_min_value_check.rb

@ -6,8 +6,9 @@ class Form::Sales::Pages::Buyer2IncomeMinValueCheck < ::Form::Page
"income2_under_soft_min?" => true, "income2_under_soft_min?" => true,
}, },
] ]
@copy_key = "sales.soft_validations.income2_value_check.min"
@title_text = { @title_text = {
"translation" => "soft_validations.income.under_soft_min_for_economic_status.title_text", "translation" => "forms.#{form.start_date.year}.#{@copy_key}.title_text",
"arguments" => [ "arguments" => [
{ {
"key" => "field_formatted_as_currency", "key" => "field_formatted_as_currency",
@ -22,7 +23,7 @@ class Form::Sales::Pages::Buyer2IncomeMinValueCheck < ::Form::Page
], ],
} }
@informative_text = { @informative_text = {
"translation" => "soft_validations.income.under_soft_min_for_economic_status.hint_text", "translation" => "forms.#{form.start_date.year}.#{@copy_key}.informative_text",
"arguments" => [], "arguments" => [],
} }
end end

3
app/models/form/sales/pages/combined_income_max_value_check.rb

@ -6,8 +6,9 @@ class Form::Sales::Pages::CombinedIncomeMaxValueCheck < ::Form::Page
"combined_income_over_soft_max?" => true, "combined_income_over_soft_max?" => true,
}, },
] ]
@copy_key = "sales.soft_validations.combined_income_value_check"
@title_text = { @title_text = {
"translation" => "soft_validations.income.over_soft_max_for_la_combined", "translation" => "forms.#{form.start_date.year}.#{@copy_key}.title_text",
"arguments" => [ "arguments" => [
{ {
"key" => "field_formatted_as_currency", "key" => "field_formatted_as_currency",

5
app/models/form/sales/pages/deposit_value_check.rb

@ -1,12 +1,13 @@
class Form::Sales::Pages::DepositValueCheck < ::Form::Page class Form::Sales::Pages::DepositValueCheck < ::Form::Page
def initialize(id, hsh, subsection, joint_purchase:) def initialize(id, hsh, subsection, joint_purchase:)
super(id, hsh, subsection) super(id, hsh, subsection)
@copy_key = "sales.soft_validations.deposit_value_check.#{joint_purchase ? 'joint_purchase' : 'not_joint_purchase'}"
@informative_text = { @informative_text = {
"translation" => "soft_validations.deposit.hint_text", "translation" => "forms.#{form.start_date.year}.#{@copy_key}.informative_text",
"arguments" => [], "arguments" => [],
} }
@title_text = { @title_text = {
"translation" => "soft_validations.deposit.title_text.#{joint_purchase ? 'two' : 'one'}", "translation" => "forms.#{form.start_date.year}.#{@copy_key}.title_text",
"arguments" => [ "arguments" => [
{ {
"key" => "field_formatted_as_currency", "key" => "field_formatted_as_currency",

1
app/models/form/sales/pages/housing_benefits.rb

@ -2,6 +2,7 @@ class Form::Sales::Pages::HousingBenefits < ::Form::Page
def initialize(id, hsh, subsection, joint_purchase:) def initialize(id, hsh, subsection, joint_purchase:)
super(id, hsh, subsection) super(id, hsh, subsection)
@joint_purchase = joint_purchase @joint_purchase = joint_purchase
@copy_key = "sales.income_benefits_and_savings.housing_benefits.#{joint_purchase ? 'joint_purchase' : 'not_joint_purchase'}"
end end
def questions def questions

6
app/models/form/sales/pages/mortgage_value_check.rb

@ -2,10 +2,10 @@ class Form::Sales::Pages::MortgageValueCheck < ::Form::Page
def initialize(id, hsh, subsection, person_index = nil) def initialize(id, hsh, subsection, person_index = nil)
super(id, hsh, subsection) super(id, hsh, subsection)
@depends_on = depends_on @depends_on = depends_on
@informative_text = {}
@person_index = person_index @person_index = person_index
@copy_key = "sales.soft_validations.mortgage_value_check"
@title_text = { @title_text = {
"translation" => "soft_validations.mortgage.title_text", "translation" => "forms.#{form.start_date.year}.#{@copy_key}.title_text",
"arguments" => [ "arguments" => [
{ {
"key" => "field_formatted_as_currency", "key" => "field_formatted_as_currency",
@ -15,7 +15,7 @@ class Form::Sales::Pages::MortgageValueCheck < ::Form::Page
], ],
} }
@informative_text = { @informative_text = {
"translation" => "soft_validations.mortgage.hint_text", "translation" => "forms.#{form.start_date.year}.#{@copy_key}.informative_text",
"arguments" => [], "arguments" => [],
} }
end end

1
app/models/form/sales/pages/previous_ownership.rb

@ -3,6 +3,7 @@ class Form::Sales::Pages::PreviousOwnership < ::Form::Page
super(id, hsh, subsection) super(id, hsh, subsection)
@joint_purchase = joint_purchase @joint_purchase = joint_purchase
@depends_on = [{ "joint_purchase?" => @joint_purchase }] @depends_on = [{ "joint_purchase?" => @joint_purchase }]
@copy_key = "sales.income_benefits_and_savings.prevown.#{joint_purchase ? 'joint_purchase' : 'not_joint_purchase'}"
end end
def questions def questions

1
app/models/form/sales/pages/savings.rb

@ -2,6 +2,7 @@ class Form::Sales::Pages::Savings < ::Form::Page
def initialize(id, hsh, subsection, joint_purchase:) def initialize(id, hsh, subsection, joint_purchase:)
super(id, hsh, subsection) super(id, hsh, subsection)
@joint_purchase = joint_purchase @joint_purchase = joint_purchase
@copy_key = "sales.income_benefits_and_savings.savings.#{joint_purchase ? 'joint_purchase' : 'not_joint_purchase'}"
end end
def questions def questions

5
app/models/form/sales/pages/savings_value_check.rb

@ -1,8 +1,9 @@
class Form::Sales::Pages::SavingsValueCheck < ::Form::Page class Form::Sales::Pages::SavingsValueCheck < ::Form::Page
def initialize(id, hsh, subsection, joint_purchase:) def initialize(id, hsh, subsection, joint_purchase:)
super(id, hsh, subsection) super(id, hsh, subsection)
@copy_key = "sales.soft_validations.savings_value_check.#{joint_purchase ? 'joint_purchase' : 'not_joint_purchase'}"
@title_text = { @title_text = {
"translation" => "soft_validations.savings.title_text.#{joint_purchase ? 'two' : 'one'}", "translation" => "forms.#{form.start_date.year}.#{@copy_key}.title_text",
"arguments" => [ "arguments" => [
{ {
"key" => "field_formatted_as_currency", "key" => "field_formatted_as_currency",
@ -12,7 +13,7 @@ class Form::Sales::Pages::SavingsValueCheck < ::Form::Page
], ],
} }
@informative_text = { @informative_text = {
"translation" => "soft_validations.savings.hint_text", "translation" => "forms.#{form.start_date.year}.#{@copy_key}.informative_text",
"arguments" => [], "arguments" => [],
} }
@joint_purchase = joint_purchase @joint_purchase = joint_purchase

4
app/models/form/sales/questions/buyer1_income.rb

@ -2,9 +2,7 @@ class Form::Sales::Questions::Buyer1Income < ::Form::Question
def initialize(id, hsh, page) def initialize(id, hsh, page)
super super
@id = "income1" @id = "income1"
@check_answer_label = "Buyer 1’s gross annual income" @copy_key = "sales.income_benefits_and_savings.buyer_1_income.income1"
@header = "Buyer 1’s gross annual income"
@hint_text = "Provide the gross annual income (i.e. salary before tax) plus the annual amount of benefits, Universal Credit or pensions, and income from investments."
@type = "numeric" @type = "numeric"
@min = 0 @min = 0
@max = 999_999 @max = 999_999

3
app/models/form/sales/questions/buyer1_income_known.rb

@ -2,8 +2,7 @@ class Form::Sales::Questions::Buyer1IncomeKnown < ::Form::Question
def initialize(id, hsh, page) def initialize(id, hsh, page)
super super
@id = "income1nk" @id = "income1nk"
@check_answer_label = "Buyer 1’s gross annual income known?" @copy_key = "sales.income_benefits_and_savings.buyer_1_income.income1nk"
@header = "Do you know buyer 1’s annual income?"
@type = "radio" @type = "radio"
@answer_options = ANSWER_OPTIONS @answer_options = ANSWER_OPTIONS
@conditional_for = { @conditional_for = {

3
app/models/form/sales/questions/buyer1_income_value_check.rb

@ -2,8 +2,7 @@ class Form::Sales::Questions::Buyer1IncomeValueCheck < ::Form::Question
def initialize(id, hsh, page, check_answers_card_number:) def initialize(id, hsh, page, check_answers_card_number:)
super(id, hsh, page) super(id, hsh, page)
@id = "income1_value_check" @id = "income1_value_check"
@check_answer_label = "Buyer 1 income confirmation" @copy_key = "sales.soft_validations.income1_value_check"
@header = "Are you sure this is correct?"
@type = "interruption_screen" @type = "interruption_screen"
@answer_options = { @answer_options = {
"0" => { "value" => "Yes" }, "0" => { "value" => "Yes" },

2
app/models/form/sales/questions/buyer1_mortgage.rb

@ -2,8 +2,6 @@ class Form::Sales::Questions::Buyer1Mortgage < ::Form::Question
def initialize(id, hsh, page) def initialize(id, hsh, page)
super super
@id = "inc1mort" @id = "inc1mort"
@check_answer_label = "Buyer 1’s income used for mortgage application"
@header = "Was buyer 1’s income used for a mortgage application?"
@type = "radio" @type = "radio"
@answer_options = ANSWER_OPTIONS @answer_options = ANSWER_OPTIONS
@check_answers_card_number = 1 @check_answers_card_number = 1

4
app/models/form/sales/questions/buyer2_income.rb

@ -2,10 +2,8 @@ class Form::Sales::Questions::Buyer2Income < ::Form::Question
def initialize(id, hsh, page) def initialize(id, hsh, page)
super super
@id = "income2" @id = "income2"
@check_answer_label = "Buyer 2’s gross annual income" @copy_key = "sales.income_benefits_and_savings.buyer_2_income.income2"
@header = "Buyer 2’s gross annual income"
@type = "numeric" @type = "numeric"
@hint_text = "Provide the gross annual income (i.e. salary before tax) plus the annual amount of benefits, Universal Credit or pensions, and income from investments."
@min = 0 @min = 0
@max = 999_999 @max = 999_999
@step = 1 @step = 1

3
app/models/form/sales/questions/buyer2_income_known.rb

@ -2,8 +2,7 @@ class Form::Sales::Questions::Buyer2IncomeKnown < ::Form::Question
def initialize(id, hsh, page) def initialize(id, hsh, page)
super super
@id = "income2nk" @id = "income2nk"
@check_answer_label = "Buyer 2’s gross annual income known?" @copy_key = "sales.income_benefits_and_savings.buyer_2_income.income2"
@header = "Do you know buyer 2’s annual income?"
@type = "radio" @type = "radio"
@answer_options = ANSWER_OPTIONS @answer_options = ANSWER_OPTIONS
@conditional_for = { @conditional_for = {

3
app/models/form/sales/questions/buyer2_income_value_check.rb

@ -2,8 +2,7 @@ class Form::Sales::Questions::Buyer2IncomeValueCheck < ::Form::Question
def initialize(id, hsh, page, check_answers_card_number:) def initialize(id, hsh, page, check_answers_card_number:)
super(id, hsh, page) super(id, hsh, page)
@id = "income2_value_check" @id = "income2_value_check"
@check_answer_label = "Buyer 2 income confirmation" @copy_key = "sales.soft_validations.income2_value_check"
@header = "Are you sure this is correct?"
@type = "interruption_screen" @type = "interruption_screen"
@answer_options = { @answer_options = {
"0" => { "value" => "Yes" }, "0" => { "value" => "Yes" },

2
app/models/form/sales/questions/buyer2_mortgage.rb

@ -2,8 +2,6 @@ class Form::Sales::Questions::Buyer2Mortgage < ::Form::Question
def initialize(id, hsh, page) def initialize(id, hsh, page)
super super
@id = "inc2mort" @id = "inc2mort"
@check_answer_label = "Buyer 2’s income used for mortgage application"
@header = "Was buyer 2’s income used for a mortgage application?"
@type = "radio" @type = "radio"
@answer_options = ANSWER_OPTIONS @answer_options = ANSWER_OPTIONS
@check_answers_card_number = 2 @check_answers_card_number = 2

3
app/models/form/sales/questions/combined_income_value_check.rb

@ -2,8 +2,7 @@ class Form::Sales::Questions::CombinedIncomeValueCheck < ::Form::Question
def initialize(id, hsh, page, check_answers_card_number:) def initialize(id, hsh, page, check_answers_card_number:)
super(id, hsh, page) super(id, hsh, page)
@id = "combined_income_value_check" @id = "combined_income_value_check"
@check_answer_label = "Combined income confirmation" @copy_key = "sales.soft_validations.combined_income_value_check"
@header = "Are you sure this is correct?"
@type = "interruption_screen" @type = "interruption_screen"
@answer_options = { @answer_options = {
"0" => { "value" => "Yes" }, "0" => { "value" => "Yes" },

3
app/models/form/sales/questions/deposit_value_check.rb

@ -2,8 +2,7 @@ class Form::Sales::Questions::DepositValueCheck < ::Form::Question
def initialize(id, hsh, page) def initialize(id, hsh, page)
super super
@id = "deposit_value_check" @id = "deposit_value_check"
@check_answer_label = "Deposit confirmation" @copy_key = "sales.soft_validations.deposit_value_check"
@header = "Are you sure that the deposit is this much higher than the buyer's savings?"
@type = "interruption_screen" @type = "interruption_screen"
@answer_options = { @answer_options = {
"0" => { "value" => "Yes" }, "0" => { "value" => "Yes" },

3
app/models/form/sales/questions/housing_benefits.rb

@ -2,8 +2,7 @@ class Form::Sales::Questions::HousingBenefits < ::Form::Question
def initialize(id, hsh, page, joint_purchase:) def initialize(id, hsh, page, joint_purchase:)
super(id, hsh, page) super(id, hsh, page)
@id = "hb" @id = "hb"
@check_answer_label = "Housing-related benefits #{joint_purchase ? 'buyers' : 'buyer'} received before buying this property" @copy_key = "sales.income_benefits_and_savings.housing_benefits.#{joint_purchase ? 'joint_purchase' : 'not_joint_purchase'}"
@header = "#{joint_purchase ? 'Were the buyers' : 'Was the buyer'} receiving any of these housing-related benefits immediately before buying this property?"
@type = "radio" @type = "radio"
@answer_options = ANSWER_OPTIONS @answer_options = ANSWER_OPTIONS
@question_number = QUESTION_NUMBER_FROM_YEAR[form.start_date.year] || QUESTION_NUMBER_FROM_YEAR[QUESTION_NUMBER_FROM_YEAR.keys.max] @question_number = QUESTION_NUMBER_FROM_YEAR[form.start_date.year] || QUESTION_NUMBER_FROM_YEAR[QUESTION_NUMBER_FROM_YEAR.keys.max]

3
app/models/form/sales/questions/mortgage_value_check.rb

@ -2,8 +2,7 @@ class Form::Sales::Questions::MortgageValueCheck < ::Form::Question
def initialize(id, hsh, page) def initialize(id, hsh, page)
super super
@id = "mortgage_value_check" @id = "mortgage_value_check"
@check_answer_label = "Mortgage confirmation" @copy_key = "sales.soft_validations.mortgage_value_check"
@header = "Are you sure that the mortgage is more than 5 times the income used for the mortgage application?"
@type = "interruption_screen" @type = "interruption_screen"
@answer_options = { @answer_options = {
"0" => { "value" => "Yes" }, "0" => { "value" => "Yes" },

3
app/models/form/sales/questions/prevown.rb

@ -2,8 +2,7 @@ class Form::Sales::Questions::Prevown < ::Form::Question
def initialize(id, hsh, page, joint_purchase:) def initialize(id, hsh, page, joint_purchase:)
super(id, hsh, page) super(id, hsh, page)
@id = "prevown" @id = "prevown"
@check_answer_label = I18n.t("check_answer_labels.prevown", count: joint_purchase ? 2 : 1) @copy_key = "sales.income_benefits_and_savings.prevown.#{joint_purchase ? 'joint_purchase' : 'not_joint_purchase'}"
@header = I18n.t("questions.prevown", count: joint_purchase ? 2 : 1)
@type = "radio" @type = "radio"
@answer_options = ANSWER_OPTIONS @answer_options = ANSWER_OPTIONS
@question_number = QUESTION_NUMBER_FROM_YEAR[form.start_date.year] || QUESTION_NUMBER_FROM_YEAR[QUESTION_NUMBER_FROM_YEAR.keys.max] @question_number = QUESTION_NUMBER_FROM_YEAR[form.start_date.year] || QUESTION_NUMBER_FROM_YEAR[QUESTION_NUMBER_FROM_YEAR.keys.max]

3
app/models/form/sales/questions/prevshared.rb

@ -2,11 +2,8 @@ class Form::Sales::Questions::Prevshared < ::Form::Question
def initialize(id, hsh, page) def initialize(id, hsh, page)
super super
@id = "prevshared" @id = "prevshared"
@check_answer_label = "Previous property shared ownership?"
@header = "Was the previous property under shared ownership?"
@type = "radio" @type = "radio"
@answer_options = ANSWER_OPTIONS @answer_options = ANSWER_OPTIONS
@hint_text = "For any buyer"
@question_number = QUESTION_NUMBER_FROM_YEAR[form.start_date.year] || QUESTION_NUMBER_FROM_YEAR[QUESTION_NUMBER_FROM_YEAR.keys.max] @question_number = QUESTION_NUMBER_FROM_YEAR[form.start_date.year] || QUESTION_NUMBER_FROM_YEAR[QUESTION_NUMBER_FROM_YEAR.keys.max]
end end

3
app/models/form/sales/questions/savings.rb

@ -2,8 +2,7 @@ class Form::Sales::Questions::Savings < ::Form::Question
def initialize(id, hsh, page, joint_purchase:) def initialize(id, hsh, page, joint_purchase:)
super(id, hsh, page) super(id, hsh, page)
@id = "savings" @id = "savings"
@check_answer_label = "#{joint_purchase ? 'Buyers’' : 'Buyer’s'} total savings before any deposit paid" @copy_key = "sales.income_benefits_and_savings.savings.#{joint_purchase ? 'joint_purchase' : 'not_joint_purchase'}.savings"
@header = "Enter their total savings to the nearest £10"
@type = "numeric" @type = "numeric"
@width = 5 @width = 5
@prefix = "£" @prefix = "£"

3
app/models/form/sales/questions/savings_nk.rb

@ -2,8 +2,7 @@ class Form::Sales::Questions::SavingsNk < ::Form::Question
def initialize(id, hsh, page, joint_purchase:) def initialize(id, hsh, page, joint_purchase:)
super(id, hsh, page) super(id, hsh, page)
@id = "savingsnk" @id = "savingsnk"
@check_answer_label = "#{joint_purchase ? 'Buyers’' : 'Buyer’s'} total savings known?" @copy_key = "sales.income_benefits_and_savings.savings.#{joint_purchase ? 'joint_purchase' : 'not_joint_purchase'}.savingsnk"
@header = "Do you know how much the #{joint_purchase ? 'buyers' : 'buyer'} had in savings before they paid any deposit for the property?"
@type = "radio" @type = "radio"
@answer_options = ANSWER_OPTIONS @answer_options = ANSWER_OPTIONS
@conditional_for = { @conditional_for = {

3
app/models/form/sales/questions/savings_value_check.rb

@ -2,8 +2,7 @@ class Form::Sales::Questions::SavingsValueCheck < ::Form::Question
def initialize(id, hsh, page) def initialize(id, hsh, page)
super super
@id = "savings_value_check" @id = "savings_value_check"
@check_answer_label = "Savings confirmation" @copy_key = "sales.soft_validations.savings_value_check"
@header = "Are you sure the savings are higher than £100,000?"
@type = "interruption_screen" @type = "interruption_screen"
@answer_options = { @answer_options = {
"0" => { "value" => "Yes" }, "0" => { "value" => "Yes" },

2
app/models/form/sales/questions/uprn.rb

@ -16,7 +16,7 @@ class Form::Sales::Questions::Uprn < ::Form::Question
end end
def unanswered_error_message def unanswered_error_message
I18n.t("validations.property.uprn.invalid") I18n.t("validations.sales.property_information.uprn.invalid")
end end
def get_extra_check_answer_value(log) def get_extra_check_answer_value(log)

2
app/models/form/sales/questions/uprn_known.rb

@ -31,7 +31,7 @@ class Form::Sales::Questions::UprnKnown < ::Form::Question
}.freeze }.freeze
def unanswered_error_message def unanswered_error_message
I18n.t("validations.property.uprn_known.invalid") I18n.t("validations.sales.property_information.uprn_known.invalid")
end end
QUESTION_NUMBER_FROM_YEAR = { 2023 => 14, 2024 => 15 }.freeze QUESTION_NUMBER_FROM_YEAR = { 2023 => 14, 2024 => 15 }.freeze

48
app/models/validations/sales/household_validations.rb

@ -9,9 +9,9 @@ module Validations::Sales::HouseholdValidations
return unless record.form.start_date.year >= 2023 return unless record.form.start_date.year >= 2023
if record.buyers_will_live_in? && record.buyer_one_will_not_live_in_property? && record.buyer_two_will_not_live_in_property? if record.buyers_will_live_in? && record.buyer_one_will_not_live_in_property? && record.buyer_two_will_not_live_in_property?
record.errors.add :buylivein, I18n.t("validations.household.buylivein.buyers_will_live_in_property_values_inconsistent_setup") record.errors.add :buylivein, I18n.t("validations.sales.household.buylivein.buyers_will_live_in_property_values_inconsistent")
record.errors.add :buy1livein, I18n.t("validations.household.buylivein.buyers_will_live_in_property_values_inconsistent") record.errors.add :buy1livein, I18n.t("validations.sales.household.buy1livein.buyers_will_live_in_property_values_inconsistent")
record.errors.add :buy2livein, I18n.t("validations.household.buylivein.buyers_will_live_in_property_values_inconsistent") record.errors.add :buy2livein, I18n.t("validations.sales.household.buy2livein.buyers_will_live_in_property_values_inconsistent")
end end
end end
@ -20,8 +20,8 @@ module Validations::Sales::HouseholdValidations
return unless record.discounted_ownership_sale? && record.prevten return unless record.discounted_ownership_sale? && record.prevten
if [3, 4, 5, 6, 7, 9, 0].include?(record.prevten) if [3, 4, 5, 6, 7, 9, 0].include?(record.prevten)
record.errors.add :prevten, I18n.t("validations.household.prevten.invalid_for_discounted_sale") record.errors.add :prevten, I18n.t("validations.sales.household.prevten.prevten_invalid_for_discounted_sale")
record.errors.add :ownershipsch, I18n.t("validations.household.prevten.invalid_for_discounted_sale") record.errors.add :ownershipsch, I18n.t("validations.sales.household.ownershipsch.prevten_invalid_for_discounted_sale")
end end
end end
@ -34,11 +34,11 @@ module Validations::Sales::HouseholdValidations
next unless age && relationship next unless age && relationship
if age < 16 && !relationship_is_child_other_or_refused?(relationship) if age < 16 && !relationship_is_child_other_or_refused?(relationship)
record.errors.add "age#{person_num}", I18n.t("validations.household.age.child_under_16_relat_sales", person_num:) record.errors.add "age#{person_num}", I18n.t("validations.sales.household.age.child_under_16", person_num:)
record.errors.add "relat#{person_num}", I18n.t("validations.household.relat.child_under_16_sales", person_num:) record.errors.add "relat#{person_num}", I18n.t("validations.sales.household.relat.child_under_16", person_num:)
elsif age >= 20 && person_is_child?(relationship) elsif age >= 20 && person_is_child?(relationship)
record.errors.add "age#{person_num}", I18n.t("validations.household.age.child_over_20") record.errors.add "age#{person_num}", I18n.t("validations.sales.household.age.child_over_20")
record.errors.add "relat#{person_num}", I18n.t("validations.household.relat.child_over_20") record.errors.add "relat#{person_num}", I18n.t("validations.sales.household.relat.child_over_20")
end end
end end
end end
@ -58,16 +58,16 @@ module Validations::Sales::HouseholdValidations
child = person_is_child?(relationship) child = person_is_child?(relationship)
if age_between_16_19 && !(student || economic_status_refused) && child if age_between_16_19 && !(student || economic_status_refused) && child
record.errors.add "ecstat#{person_num}", I18n.t("validations.household.ecstat.student_16_19.must_be_student") record.errors.add "ecstat#{person_num}", I18n.t("validations.sales.household.ecstat.student_16_19.must_be_student")
record.errors.add "age#{person_num}", I18n.t("validations.household.age.student_16_19.cannot_be_16_19.child_not_student") record.errors.add "age#{person_num}", I18n.t("validations.sales.household.age.student_16_19.cannot_be_16_19.child_not_student")
record.errors.add "relat#{person_num}", I18n.t("validations.household.relat.student_16_19.cannot_be_child.16_19_not_student") record.errors.add "relat#{person_num}", I18n.t("validations.sales.household.relat.student_16_19.cannot_be_child.16_19_not_student")
end end
next unless !age_between_16_19 && student && child next unless !age_between_16_19 && student && child
record.errors.add "age#{person_num}", I18n.t("validations.household.age.student_16_19.must_be_16_19") record.errors.add "age#{person_num}", I18n.t("validations.sales.household.age.student_16_19.must_be_16_19")
record.errors.add "ecstat#{person_num}", I18n.t("validations.household.ecstat.student_16_19.cannot_be_student.child_not_16_19") record.errors.add "ecstat#{person_num}", I18n.t("validations.sales.household.ecstat.student_16_19.cannot_be_student.child_not_16_19")
record.errors.add "relat#{person_num}", I18n.t("validations.household.relat.student_16_19.cannot_be_child.student_not_16_19") record.errors.add "relat#{person_num}", I18n.t("validations.sales.household.relat.student_16_19.cannot_be_child.student_not_16_19")
end end
end end
@ -78,12 +78,12 @@ module Validations::Sales::HouseholdValidations
next unless age && economic_status next unless age && economic_status
if age < 16 && !economic_status_is_child_other_or_refused?(economic_status) && !record.form.start_year_after_2024? if age < 16 && !economic_status_is_child_other_or_refused?(economic_status) && !record.form.start_year_after_2024?
record.errors.add "ecstat#{person_num}", I18n.t("validations.household.ecstat.child_under_16", person_num:) record.errors.add "ecstat#{person_num}", I18n.t("validations.sales.household.ecstat.child_under_16", person_num:)
record.errors.add "age#{person_num}", I18n.t("validations.household.age.child_under_16_ecstat", person_num:) record.errors.add "age#{person_num}", I18n.t("validations.sales.household.age.child_under_16_ecstat", person_num:)
end end
if person_is_economic_child?(economic_status) && age > 16 if person_is_economic_child?(economic_status) && age > 16
record.errors.add "ecstat#{person_num}", I18n.t("validations.household.ecstat.child_over_16", person_num:) record.errors.add "ecstat#{person_num}", I18n.t("validations.sales.household.ecstat.child_over_16", person_num:)
record.errors.add "age#{person_num}", I18n.t("validations.household.age.child_over_16", person_num:) record.errors.add "age#{person_num}", I18n.t("validations.sales.household.age.child_over_16", person_num:)
end end
end end
end end
@ -99,17 +99,17 @@ module Validations::Sales::HouseholdValidations
next unless person_age > buyer_1_age - 12 && person_is_child?(relationship) next unless person_age > buyer_1_age - 12 && person_is_child?(relationship)
record.errors.add "age1", I18n.t("validations.household.age.child_12_years_younger") record.errors.add "age1", I18n.t("validations.sales.household.age1.child_12_years_younger")
record.errors.add "age#{person_num}", I18n.t("validations.household.age.child_12_years_younger") record.errors.add "age#{person_num}", I18n.t("validations.sales.household.age.child_12_years_younger")
record.errors.add "relat#{person_num}", I18n.t("validations.household.age.child_12_years_younger") record.errors.add "relat#{person_num}", I18n.t("validations.sales.household.relat.child_12_years_younger")
end end
end end
def validate_buyer_not_child(record) def validate_buyer_not_child(record)
return unless record.saledate && record.form.start_year_after_2024? return unless record.saledate && record.form.start_year_after_2024?
record.errors.add "ecstat1", I18n.t("validations.household.ecstat.buyer_cannot_be_child", buyer_index: "1") if person_is_economic_child?(record.ecstat1) record.errors.add "ecstat1", I18n.t("validations.sales.household.ecstat1.buyer_cannot_be_child") if person_is_economic_child?(record.ecstat1)
record.errors.add "ecstat2", I18n.t("validations.household.ecstat.buyer_cannot_be_child", buyer_index: "2") if person_is_economic_child?(record.ecstat2) && record.joint_purchase? record.errors.add "ecstat2", I18n.t("validations.sales.household.ecstat2.buyer_cannot_be_child") if person_is_economic_child?(record.ecstat2) && record.joint_purchase?
end end
private private

15
app/models/validations/sales/property_validations.rb

@ -4,10 +4,11 @@ module Validations::Sales::PropertyValidations
return unless record.ppostcode_full.present? && record.postcode_full.present? return unless record.ppostcode_full.present? && record.postcode_full.present?
if record.discounted_ownership_sale? && record.ppostcode_full != record.postcode_full if record.discounted_ownership_sale? && record.ppostcode_full != record.postcode_full
record.errors.add :postcode_full, I18n.t("validations.property.postcode.must_match_previous", buyer_possessive: record.joint_purchase? ? "Buyers’" : "Buyer’s") joint_purchase_id = record.joint_purchase? ? "joint_purchase" : "not_joint_purchase"
record.errors.add :ppostcode_full, I18n.t("validations.property.postcode.must_match_previous", buyer_possessive: record.joint_purchase? ? "Buyers’" : "Buyer’s") record.errors.add :postcode_full, I18n.t("validations.sales.property_information.postcode_full.postcode_must_match_previous.#{joint_purchase_id}")
record.errors.add :ownershipsch, I18n.t("validations.property.postcode.must_match_previous", buyer_possessive: record.joint_purchase? ? "Buyers’" : "Buyer’s") record.errors.add :ppostcode_full, I18n.t("validations.sales.property_information.ppostcode_full.postcode_must_match_previous.#{joint_purchase_id}")
record.errors.add :uprn, I18n.t("validations.property.postcode.must_match_previous", buyer_possessive: record.joint_purchase? ? "Buyers’" : "Buyer’s") record.errors.add :ownershipsch, I18n.t("validations.sales.property_information.ownershipsch.postcode_must_match_previous.#{joint_purchase_id}")
record.errors.add :uprn, I18n.t("validations.sales.property_information.uprn.postcode_must_match_previous.#{joint_purchase_id}")
end end
end end
@ -15,8 +16,8 @@ module Validations::Sales::PropertyValidations
return unless record.proptype.present? && record.beds.present? return unless record.proptype.present? && record.beds.present?
if record.is_bedsit? && record.beds > 1 if record.is_bedsit? && record.beds > 1
record.errors.add :proptype, I18n.t("validations.property.proptype.bedsits_have_max_one_bedroom") record.errors.add :proptype, I18n.t("validations.sales.property_information.proptype.bedsits_have_max_one_bedroom")
record.errors.add :beds, I18n.t("validations.property.beds.bedsits_have_max_one_bedroom") record.errors.add :beds, I18n.t("validations.sales.property_information.beds.bedsits_have_max_one_bedroom")
end end
end end
@ -25,6 +26,6 @@ module Validations::Sales::PropertyValidations
return if record.uprn.match?(/^[0-9]{1,12}$/) return if record.uprn.match?(/^[0-9]{1,12}$/)
record.errors.add :uprn, I18n.t("validations.property.uprn.invalid") record.errors.add :uprn, I18n.t("validations.sales.property_information.uprn.invalid")
end end
end end

4
app/models/validations/shared_validations.rb

@ -131,10 +131,14 @@ module Validations::SharedValidations
partner_numbers = (2..max_people).select { |n| person_is_partner?(record["relat#{n}"]) } partner_numbers = (2..max_people).select { |n| person_is_partner?(record["relat#{n}"]) }
if partner_numbers.count > 1 if partner_numbers.count > 1
partner_numbers.each do |n| partner_numbers.each do |n|
if record.sales?
record.errors.add "relat#{n}", I18n.t("validations.sales.household.relat.one_partner")
else
record.errors.add "relat#{n}", I18n.t("validations.household.relat.one_partner") record.errors.add "relat#{n}", I18n.t("validations.household.relat.one_partner")
end end
end end
end end
end
def date_valid?(question, record) def date_valid?(question, record)
if record[question].is_a?(ActiveSupport::TimeWithZone) && record[question].year.zero? if record[question].is_a?(ActiveSupport::TimeWithZone) && record[question].year.zero?

12
app/services/bulk_upload/sales/year2024/row_parser.rb

@ -1469,10 +1469,10 @@ private
def validate_buyer1_economic_status def validate_buyer1_economic_status
if field_35 == 9 if field_35 == 9
if field_31.present? && field_31.to_i >= 16 if field_31.present? && field_31.to_i >= 16
errors.add(:field_35, I18n.t("validations.household.ecstat.buyer_cannot_be_over_16_and_child", buyer_index: "1")) errors.add(:field_35, I18n.t("validations.sales.household.ecstat.buyer_cannot_be_over_16_and_child", buyer_index: "1"))
errors.add(:field_31, I18n.t("validations.household.ecstat.buyer_cannot_be_over_16_and_child", buyer_index: "1")) errors.add(:field_31, I18n.t("validations.sales.household.ecstat.buyer_cannot_be_over_16_and_child", buyer_index: "1"))
else else
errors.add(:field_35, I18n.t("validations.household.ecstat.buyer_cannot_be_child", buyer_index: "1")) errors.add(:field_35, I18n.t("validations.sales.household.ecstat1.buyer_cannot_be_child"))
end end
end end
end end
@ -1482,10 +1482,10 @@ private
if field_42 == 9 if field_42 == 9
if field_38.present? && field_38.to_i >= 16 if field_38.present? && field_38.to_i >= 16
errors.add(:field_42, I18n.t("validations.household.ecstat.buyer_cannot_be_over_16_and_child", buyer_index: "2")) errors.add(:field_42, I18n.t("validations.sales.household.ecstat.buyer_cannot_be_over_16_and_child", buyer_index: "2"))
errors.add(:field_38, I18n.t("validations.household.ecstat.buyer_cannot_be_over_16_and_child", buyer_index: "2")) errors.add(:field_38, I18n.t("validations.sales.household.ecstat.buyer_cannot_be_over_16_and_child", buyer_index: "2"))
else else
errors.add(:field_42, I18n.t("validations.household.ecstat.buyer_cannot_be_child", buyer_index: "2")) errors.add(:field_42, I18n.t("validations.sales.household.ecstat2.buyer_cannot_be_child"))
end end
end end
end end

43
config/locales/en.yml

@ -385,12 +385,6 @@ en:
one_bedroom_bedsit: "A bedsit can only have one bedroom." one_bedroom_bedsit: "A bedsit can only have one bedroom."
one_seven_bedroom_shared: "A shared house must have 1 to 7 bedrooms." one_seven_bedroom_shared: "A shared house must have 1 to 7 bedrooms."
one_three_bedroom_single_tenant_shared: "A shared house with fewer than two tenants must have 1 to 3 bedrooms." one_three_bedroom_single_tenant_shared: "A shared house with fewer than two tenants must have 1 to 3 bedrooms."
beds:
bedsits_have_max_one_bedroom: "Number of bedrooms must be 1 if the property is a bedsit."
proptype:
bedsits_have_max_one_bedroom: "Answer cannot be 'Bedsit' if the property has 2 or more bedrooms."
postcode:
must_match_previous: "%{buyer_possessive} last accommodation and discounted ownership postcodes must match."
financial: financial:
tshortfall: tshortfall:
@ -504,11 +498,8 @@ en:
retired_female: "A female tenant who is retired must be 60 or over." retired_female: "A female tenant who is retired must be 60 or over."
retired_over_70: "Answer cannot be over 70 as person %{person_num} has economic status that is not ‘retired’." retired_over_70: "Answer cannot be over 70 as person %{person_num} has economic status that is not ‘retired’."
child_under_16_relat_lettings: "Answer cannot be under 16 as person %{person_num}'s relationship to the lead tenant is ‘partner’." child_under_16_relat_lettings: "Answer cannot be under 16 as person %{person_num}'s relationship to the lead tenant is ‘partner’."
child_under_16_relat_sales: "Answer cannot be under 16 as person %{person_num}'s relationship to buyer 1 is ‘partner’."
child_under_16_ecstat: "Answer cannot be under 16 as person %{person_num}’s working situation is not ‘child under 16’, ‘other’ or ‘prefers not to say’." child_under_16_ecstat: "Answer cannot be under 16 as person %{person_num}’s working situation is not ‘child under 16’, ‘other’ or ‘prefers not to say’."
child_over_16: "Answer cannot be over 16 as person’s %{person_num} working situation is ‘child under 16‘." child_over_16: "Answer cannot be over 16 as person’s %{person_num} working situation is ‘child under 16‘."
child_over_20: "Answer cannot be 20 or over as the relationship is ‘child’."
child_12_years_younger: "A child must be at least 12 years younger than their parent."
not_student_16_19: "Answer cannot be between 16 and 19 as person %{person_num} is a child of the lead tenant but is not a full-time student." not_student_16_19: "Answer cannot be between 16 and 19 as person %{person_num} is a child of the lead tenant but is not a full-time student."
student_16_19: student_16_19:
cannot_be_16_19: cannot_be_16_19:
@ -531,12 +522,8 @@ en:
retired_female: "Answer cannot be ‘retired’ as the female tenant is under 60." retired_female: "Answer cannot be ‘retired’ as the female tenant is under 60."
not_child_16_19: not_child_16_19:
cannot_be_student: "Person cannot be a student if they are aged 16-19 but are not a child." cannot_be_student: "Person cannot be a student if they are aged 16-19 but are not a child."
buyer_cannot_be_child: "Buyer %{buyer_index} cannot have a working situation of child under 16."
buyer_cannot_be_over_16_and_child: "Buyer %{buyer_index}'s age cannot be 16 or over if their working situation is child under 16."
relat: relat:
child_under_16_sales: "Answer cannot be ‘partner’ as you told us person %{person_num}'s age is under 16."
child_under_16_lettings: "Answer cannot be ‘partner’ as you told us person %{person_num}'s age is under 16." child_under_16_lettings: "Answer cannot be ‘partner’ as you told us person %{person_num}'s age is under 16."
child_over_20: "Answer cannot be ‘child’ if the person's age is 20 or over."
one_partner: "Number of partners cannot be greater than 1." one_partner: "Number of partners cannot be greater than 1."
not_student_16_19: "Answer cannot be ‘child’ as you told us the person %{person_num} is between 16 and 19 and is not a full-time student." not_student_16_19: "Answer cannot be ‘child’ as you told us the person %{person_num} is between 16 and 19 and is not a full-time student."
student_16_19: student_16_19:
@ -559,7 +546,6 @@ en:
internal_transfer: "Answer cannot be %{prevten} as this tenancy is an internal transfer." internal_transfer: "Answer cannot be %{prevten} as this tenancy is an internal transfer."
la_general_needs: la_general_needs:
internal_transfer: "Answer cannot be a fixed-term or lifetime local authority general needs tenancy as it’s an internal transfer and a private registered provider is on the tenancy agreement." internal_transfer: "Answer cannot be a fixed-term or lifetime local authority general needs tenancy as it’s an internal transfer and a private registered provider is on the tenancy agreement."
invalid_for_discounted_sale: "Buyer 1’s previous tenure should be “local authority tenant” or “private registered provider or housing association tenant” for discounted sales."
referral: referral:
secure_tenancy: "Answer must be internal transfer as this is a secure tenancy." secure_tenancy: "Answer must be internal transfer as this is a secure tenancy."
rsnvac_non_temp: "Answer cannot be this source of referral as this is a re-let to tenant who occupied the same property as temporary accommodation." rsnvac_non_temp: "Answer cannot be this source of referral as this is a re-let to tenant who occupied the same property as temporary accommodation."
@ -599,9 +585,6 @@ en:
no_choices: "You cannot answer this question as you told us nobody in the household has a physical or mental health condition (or other illness) expected to last 12 months or more." no_choices: "You cannot answer this question as you told us nobody in the household has a physical or mental health condition (or other illness) expected to last 12 months or more."
postcode: postcode:
discounted_ownership: "Last settled accommodation and discounted ownership property postcodes must match." discounted_ownership: "Last settled accommodation and discounted ownership property postcodes must match."
buylivein:
buyers_will_live_in_property_values_inconsistent_setup: "You have already told us that both buyer 1 and buyer 2 will not live in the property."
buyers_will_live_in_property_values_inconsistent: "You have already told us that the buyers will live in the property. Either buyer 1 or buyer 2 must live in the property."
nationality: "Select a valid nationality." nationality: "Select a valid nationality."
tenancy: tenancy:
@ -706,13 +689,6 @@ en:
message: "Net income is lower than expected based on the household’s working situation. Are you sure this is correct?" message: "Net income is lower than expected based on the household’s working situation. Are you sure this is correct?"
in_soft_max_range: in_soft_max_range:
message: "Net income is higher than expected based on the household’s working situation. Are you sure this is correct?" message: "Net income is higher than expected based on the household’s working situation. Are you sure this is correct?"
income:
under_soft_min_for_economic_status:
title_text: "You told us income was %{income}."
hint_text: "This is less than we would expect for someone in this working situation."
over_soft_max_for_la_buyer_1: "You told us the income of buyer 1 is %{income}. This seems high. Are you sure this is correct?"
over_soft_max_for_la_buyer_2: "You told us the income of buyer 2 is %{income}. This seems high. Are you sure this is correct?"
over_soft_max_for_la_combined: "You told us the combined income of this household is %{combined_income}. This seems high. Are you sure this is correct?"
rent: rent:
outside_range_title: "You told us the rent is %{brent}." outside_range_title: "You told us the rent is %{brent}."
informative_text: "This is %{higher_or_lower} than we would expect." informative_text: "This is %{higher_or_lower} than we would expect."
@ -775,24 +751,11 @@ Make sure these answers are correct."
percentage_discount_value: percentage_discount_value:
title_text: "You told us that the percentage discount is %{discount}." title_text: "You told us that the percentage discount is %{discount}."
hint_text: "This is higher than we would expect." hint_text: "This is higher than we would expect."
savings:
title_text:
one: "You told us the buyer’s savings were %{savings}."
two: "You told us the buyers’ savings were %{savings}."
hint_text: "This is higher than we would expect."
deposit:
title_text:
one: "You told us the buyer’s deposit was %{deposit} and their savings were %{savings}."
two: "You told us the buyers’ deposit was %{deposit} and their savings were %{savings}."
hint_text: "The deposit amount is higher than we would expect for the amount of savings they have."
grant: grant:
title_text: "You told us that the grant amount is %{grant}." title_text: "You told us that the grant amount is %{grant}."
hint_text: "Loans, grants and subsidies are usually between £9,000 and £16,000." hint_text: "Loans, grants and subsidies are usually between £9,000 and £16,000."
wheelchair: wheelchair:
title_text: "You told us that someone in the household uses a wheelchair." title_text: "You told us that someone in the household uses a wheelchair."
mortgage:
title_text: "You told us that the mortgage amount is %{mortgage}."
hint_text: "This is more than 5 times the income, which is higher than we would expect."
referral: referral:
title_text: "Are you sure?" title_text: "Are you sure?"
hint_text: "This is a general needs log, and this referral type is for supported housing." hint_text: "This is a general needs log, and this referral type is for supported housing."
@ -862,9 +825,6 @@ Make sure these answers are correct."
soctenant: soctenant:
one: "Was the buyer a private registered provider, housing association or local authority tenant immediately before this sale?" one: "Was the buyer a private registered provider, housing association or local authority tenant immediately before this sale?"
other: "Were any of the buyers private registered providers, housing association or local authority tenants immediately before this sale?" other: "Were any of the buyers private registered providers, housing association or local authority tenants immediately before this sale?"
prevown:
one: "Has the buyer previously owned a property?"
other: "Have any of the buyers previously owned a property?"
stairowned: stairowned:
one: "What percentage of the property does the buyer now own in total?" one: "What percentage of the property does the buyer now own in total?"
other: "What percentage of the property do the buyers now own in total?" other: "What percentage of the property do the buyers now own in total?"
@ -887,9 +847,6 @@ Make sure these answers are correct."
soctenant: soctenant:
one: "Buyer was a registered provider, housing association or local authority tenant immediately before this sale?" one: "Buyer was a registered provider, housing association or local authority tenant immediately before this sale?"
other: "Any buyers were registered providers, housing association or local authority tenants immediately before this sale?" other: "Any buyers were registered providers, housing association or local authority tenants immediately before this sale?"
prevown:
one: "Buyer previously owned a property."
other: "Buyers previously owned a property."
stairowned: stairowned:
one: "Percentage the buyer now owns in total." one: "Percentage the buyer now owns in total."
other: "Percentage the buyers now own in total." other: "Percentage the buyers now own in total."

90
config/locales/forms/2023/sales/income_benefits_and_savings.en.yml

@ -0,0 +1,90 @@
en:
forms:
2023:
sales:
income_benefits_and_savings:
buyer_1_income:
page_header: ""
income1nk:
check_answer_label: "Buyer 1’s gross annual income known?"
hint_text: ""
question_text: "Do you know buyer 1’s annual income?"
income1:
check_answer_label: "Buyer 1’s gross annual income"
hint_text: "Provide the gross annual income (i.e. salary before tax) plus the annual amount of benefits, Universal Credit or pensions, and income from investments."
question_text: "Buyer 1’s gross annual income"
inc1mort:
page_header: ""
check_answer_label: "Buyer 1’s income used for mortgage application"
hint_text: ""
question_text: "Was buyer 1’s income used for a mortgage application?"
buyer_2_income:
page_header: ""
income2nk:
check_answer_label: "Buyer 2’s gross annual income known?"
hint_text: ""
question_text: "Do you know buyer 2’s annual income?"
income2:
check_answer_label: "Buyer 2’s gross annual income"
hint_text: "Provide the gross annual income (i.e. salary before tax) plus the annual amount of benefits, Universal Credit or pensions, and income from investments."
question_text: "Buyer 2’s gross annual income"
inc2mort:
page_header: ""
check_answer_label: "Buyer 2’s income used for mortgage application"
hint_text: ""
question_text: "Was buyer 2’s income used for a mortgage application?"
housing_benefits:
joint_purchase:
page_header: ""
check_answer_label: "Housing-related benefits buyers received before buying this property"
hint_text: ""
question_text: "Were the buyers receiving any of these housing-related benefits immediately before buying this property?"
not_joint_purchase:
page_header: ""
check_answer_label: "Housing-related benefits buyer received before buying this property"
hint_text: ""
question_text: "Was the buyer receiving any of these housing-related benefits immediately before buying this property?"
savings:
joint_purchase:
page_header: ""
savingsnk:
check_answer_label: "Buyers’ total savings known?"
hint_text: ""
question_text: "Do you know how much the 'buyers' had in savings before they paid any deposit for the property?"
savings:
check_answer_label: "Buyers’ total savings before any deposit paid"
hint_text: "Include any savings, investments, ISAs, premium bonds, shares, or money held in a bank or building society account."
question_text: "Enter their total savings to the nearest £10"
not_joint_purchase:
page_header: ""
savingsnk:
check_answer_label: "Buyer’s total savings known?"
hint_text: ""
question_text: "Do you know how much the buyer had in savings before they paid any deposit for the property?"
savings:
check_answer_label: "Buyer’s total savings before any deposit paid"
hint_text: "Include any savings, investments, ISAs, premium bonds, shares, or money held in a bank or building society account."
question_text: "Enter their total savings to the nearest £10"
prevown:
joint_purchase:
page_header: ""
check_answer_label: "Buyers previously owned a property."
hint_text: ""
question_text: "Have any of the buyers previously owned a property?"
not_joint_purchase:
page_header: ""
check_answer_label: "Buyer previously owned a property."
hint_text: ""
question_text: "Has the buyer previously owned a property?"
prevshared:
page_header: ""
check_answer_label: "Previous property shared ownership?"
hint_text: "For any buyer"
question_text: "Was the previous property under shared ownership?"

60
config/locales/forms/2023/sales/soft_validations.en.yml

@ -0,0 +1,60 @@
en:
forms:
2023:
sales:
soft_validations:
income1_value_check:
page_header: ""
check_answer_label: "Buyer 1 income confirmation"
hint_text: ""
question_text: "Are you sure this is correct?"
min:
title_text: "You told us income was %{income}."
informative_text: "This is less than we would expect for someone in this working situation."
max:
title_text: "You told us the income of buyer 1 is %{income}. This seems high. Are you sure this is correct?"
income2_value_check:
page_header: ""
check_answer_label: "Buyer 2 income confirmation"
hint_text: ""
question_text: "Are you sure this is correct?"
min:
title_text: "You told us income was %{income}."
informative_text: "This is less than we would expect for someone in this working situation."
max:
title_text: "You told us the income of buyer 2 is %{income}. This seems high. Are you sure this is correct?"
combined_income_value_check:
page_header: ""
check_answer_label: "Combined income confirmation"
hint_text: ""
question_text: "Are you sure this is correct?"
title_text: "You told us the combined income of this household is %{combined_income}. This seems high. Are you sure this is correct?"
mortgage_value_check:
page_header: ""
check_answer_label: "Mortgage confirmation"
hint_text: ""
question_text: "Are you sure that the mortgage is more than 5 times the income used for the mortgage application?"
title_text: "You told us that the mortgage amount is %{mortgage}."
informative_text: "This is more than 5 times the income, which is higher than we would expect."
savings_value_check:
page_header: ""
check_answer_label: "Savings confirmation"
hint_text: ""
question_text: "Are you sure the savings are higher than £100,000?"
joint_purchase:
title_text: You told us the buyers’ savings were %{savings}."
informative_text: "This is higher than we would expect."
not_joint_purchase:
title_text: "You told us the buyer’s savings were %{savings}."
informative_text: "This is higher than we would expect."
deposit_value_check::
page_header: ""
check_answer_label: "Deposit confirmation"
hint_text: ""
question_text: "Are you sure that the deposit is this much higher than the buyer's savings?"
joint_purchase:
title_text: "You told us the buyers’ deposit was %{deposit} and their savings were %{savings}."
informative_text: "The deposit amount is higher than we would expect for the amount of savings they have."
not_joint_purchase:
title_text: "You told us the buyer’s deposit was %{deposit} and their savings were %{savings}."
informative_text: "The deposit amount is higher than we would expect for the amount of savings they have."

90
config/locales/forms/2024/sales/income_benefits_and_savings.en.yml

@ -0,0 +1,90 @@
en:
forms:
2024:
sales:
income_benefits_and_savings:
buyer_1_income:
page_header: ""
income1nk:
check_answer_label: "Buyer 1’s gross annual income known?"
hint_text: ""
question_text: "Do you know buyer 1’s annual income?"
income1:
check_answer_label: "Buyer 1’s gross annual income"
hint_text: "Provide the gross annual income (i.e. salary before tax) plus the annual amount of benefits, Universal Credit or pensions, and income from investments."
question_text: "Buyer 1’s gross annual income"
inc1mort:
page_header: ""
check_answer_label: "Buyer 1’s income used for mortgage application"
hint_text: ""
question_text: "Was buyer 1’s income used for a mortgage application?"
buyer_2_income:
page_header: ""
income2nk:
check_answer_label: "Buyer 2’s gross annual income known?"
hint_text: ""
question_text: "Do you know buyer 2’s annual income?"
income2:
check_answer_label: "Buyer 2’s gross annual income"
hint_text: "Provide the gross annual income (i.e. salary before tax) plus the annual amount of benefits, Universal Credit or pensions, and income from investments."
question_text: "Buyer 2’s gross annual income"
inc2mort:
page_header: ""
check_answer_label: "Buyer 2’s income used for mortgage application"
hint_text: ""
question_text: "Was buyer 2’s income used for a mortgage application?"
housing_benefits:
joint_purchase:
page_header: ""
check_answer_label: "Housing-related benefits buyers received before buying this property"
hint_text: ""
question_text: "Were the buyers receiving any of these housing-related benefits immediately before buying this property?"
not_joint_purchase:
page_header: ""
check_answer_label: "Housing-related benefits buyer received before buying this property"
hint_text: ""
question_text: "Was the buyer receiving any of these housing-related benefits immediately before buying this property?"
savings:
joint_purchase:
page_header: ""
savingsnk:
check_answer_label: "Buyers’ total savings known?"
hint_text: ""
question_text: "Do you know how much the 'buyers' had in savings before they paid any deposit for the property?"
savings:
check_answer_label: "Buyers’ total savings before any deposit paid"
hint_text: "Include any savings, investments, ISAs, premium bonds, shares, or money held in a bank or building society account."
question_text: "Enter their total savings to the nearest £10"
not_joint_purchase:
page_header: ""
savingsnk:
check_answer_label: "Buyer’s total savings known?"
hint_text: ""
question_text: "Do you know how much the buyer had in savings before they paid any deposit for the property?"
savings:
check_answer_label: "Buyer’s total savings before any deposit paid"
hint_text: "Include any savings, investments, ISAs, premium bonds, shares, or money held in a bank or building society account."
question_text: "Enter their total savings to the nearest £10"
prevown:
joint_purchase:
page_header: ""
check_answer_label: "Buyers previously owned a property."
hint_text: ""
question_text: "Have any of the buyers previously owned a property?"
not_joint_purchase:
page_header: ""
check_answer_label: "Buyer previously owned a property."
hint_text: ""
question_text: "Has the buyer previously owned a property?"
prevshared:
page_header: ""
check_answer_label: "Previous property shared ownership?"
hint_text: "For any buyer"
question_text: "Was the previous property under shared ownership?"

60
config/locales/forms/2024/sales/soft_validations.en.yml

@ -0,0 +1,60 @@
en:
forms:
2024:
sales:
soft_validations:
income1_value_check:
page_header: ""
check_answer_label: "Buyer 1 income confirmation"
hint_text: ""
question_text: "Are you sure this is correct?"
min:
title_text: "You told us income was %{income}."
informative_text: "This is less than we would expect for someone in this working situation."
max:
title_text: "You told us the income of buyer 1 is %{income}. This seems high. Are you sure this is correct?"
income2_value_check:
page_header: ""
check_answer_label: "Buyer 2 income confirmation"
hint_text: ""
question_text: "Are you sure this is correct?"
min:
title_text: "You told us income was %{income}."
informative_text: "This is less than we would expect for someone in this working situation."
max:
title_text: "You told us the income of buyer 2 is %{income}. This seems high. Are you sure this is correct?"
combined_income_value_check:
page_header: ""
check_answer_label: "Combined income confirmation"
hint_text: ""
question_text: "Are you sure this is correct?"
title_text: "You told us the combined income of this household is %{combined_income}. This seems high. Are you sure this is correct?"
mortgage_value_check:
page_header: ""
check_answer_label: "Mortgage confirmation"
hint_text: ""
question_text: "Are you sure that the mortgage is more than 5 times the income used for the mortgage application?"
title_text: "You told us that the mortgage amount is %{mortgage}."
informative_text: "This is more than 5 times the income, which is higher than we would expect."
savings_value_check:
page_header: ""
check_answer_label: "Savings confirmation"
hint_text: ""
question_text: "Are you sure the savings are higher than £100,000?"
joint_purchase:
title_text: You told us the buyers’ savings were %{savings}."
informative_text: "This is higher than we would expect."
not_joint_purchase:
title_text: "You told us the buyer’s savings were %{savings}."
informative_text: "This is higher than we would expect."
deposit_value_check:
page_header: ""
check_answer_label: "Deposit confirmation"
hint_text: ""
question_text: "Are you sure that the deposit is this much higher than the buyer's savings?"
joint_purchase:
title_text: "You told us the buyers’ deposit was %{deposit} and their savings were %{savings}."
informative_text: "The deposit amount is higher than we would expect for the amount of savings they have."
not_joint_purchase:
title_text: "You told us the buyer’s deposit was %{deposit} and their savings were %{savings}."
informative_text: "The deposit amount is higher than we would expect for the amount of savings they have."

47
config/locales/validations/sales/household.en.yml

@ -0,0 +1,47 @@
en:
validations:
sales:
household:
buylivein:
buyers_will_live_in_property_values_inconsistent: "You have already told us that both buyer 1 and buyer 2 will not live in the property."
buy1livein:
buyers_will_live_in_property_values_inconsistent: "You have already told us that the buyers will live in the property. Either buyer 1 or buyer 2 must live in the property."
buy2livein:
buyers_will_live_in_property_values_inconsistent: "You have already told us that the buyers will live in the property. Either buyer 1 or buyer 2 must live in the property."
ownershipsch:
prevten_invalid_for_discounted_sale: "Buyer 1’s previous tenure should be “local authority tenant” or “private registered provider or housing association tenant” for discounted sales."
prevten:
prevten_invalid_for_discounted_sale: "Buyer 1’s previous tenure should be “local authority tenant” or “private registered provider or housing association tenant” for discounted sales."
age1:
child_12_years_younger: "A child must be at least 12 years younger than their parent."
ecstat1:
buyer_cannot_be_child: "Buyer 1 cannot have a working situation of child under 16."
ecstat2:
buyer_cannot_be_child: "Buyer 2 cannot have a working situation of child under 16."
age:
child_12_years_younger: "A child must be at least 12 years younger than their parent."
child_under_16: "Answer cannot be under 16 as person %{person_num}'s relationship to buyer 1 is ‘partner’."
child_under_16_ecstat: "Answer cannot be under 16 as person %{person_num}’s working situation is not ‘child under 16’, ‘other’ or ‘prefers not to say’."
child_over_16: "Answer cannot be over 16 as person’s %{person_num} working situation is ‘child under 16‘."
child_over_20: "Answer cannot be 20 or over as the relationship is ‘child’."
student_16_19:
cannot_be_16_19:
child_not_student: "Person cannot be aged 16-19 if they have relationship ‘child’ but are not a student."
must_be_16_19: "Person must be aged 16-19 if they are a student and have relationship ‘child’."
relat:
one_partner: "Number of partners cannot be greater than 1."
child_12_years_younger: "A child must be at least 12 years younger than their parent."
child_under_16: "Answer cannot be ‘partner’ as you told us person %{person_num}'s age is under 16."
child_over_20: "Answer cannot be ‘child’ if the person's age is 20 or over."
student_16_19:
cannot_be_child:
student_not_16_19: "Answer cannot be ‘child’ if the person is a student but not aged 16-19."
16_19_not_student: "Answer cannot be ‘child’ if the person is aged 16-19 but not a student."
ecstat:
child_under_16: "Person %{person_num}’s working situation must be ‘child under 16’, ‘other’ or ‘prefers not to say’ as you told us they’re under 16."
child_over_16: "Answer cannot be ‘child under 16’ as you told us the person %{person_num} is older than 16."
student_16_19:
must_be_student: "Person must be a student if they are aged 16-19 and have relationship ‘child’."
cannot_be_student:
child_not_16_19: "Person cannot be a student if they are not aged 16-19 but have relationship ‘child’."
buyer_cannot_be_over_16_and_child: "Buyer %{buyer_index}'s age cannot be 16 or over if their working situation is child under 16."

27
config/locales/validations/sales/property_information.en.yml

@ -0,0 +1,27 @@
en:
validations:
sales:
property_information:
postcode_full:
postcode_must_match_previous:
joint_purchase: "Buyers’ last accommodation and discounted ownership postcodes must match."
not_joint_purchase: "Buyer’s last accommodation and discounted ownership postcodes must match."
ppostcode_full:
postcode_must_match_previous:
joint_purchase: "Buyers’ last accommodation and discounted ownership postcodes must match."
not_joint_purchase: "Buyer’s last accommodation and discounted ownership postcodes must match."
ownershipsch:
postcode_must_match_previous:
joint_purchase: "Buyers’ last accommodation and discounted ownership postcodes must match."
not_joint_purchase: "Buyer’s last accommodation and discounted ownership postcodes must match."
uprn:
postcode_must_match_previous:
joint_purchase: "Buyers’ last accommodation and discounted ownership postcodes must match."
not_joint_purchase: "Buyer’s last accommodation and discounted ownership postcodes must match."
invalid: "UPRN must be 12 digits or less."
beds:
bedsits_have_max_one_bedroom: "Number of bedrooms must be 1 if the property is a bedsit."
proptype:
bedsits_have_max_one_bedroom: "Answer cannot be 'Bedsit' if the property has 2 or more bedrooms."
uprn_known:
invalid: "You must answer UPRN known?"

3
spec/models/form/sales/pages/buyer1_income_max_value_check_spec.rb

@ -5,7 +5,8 @@ RSpec.describe Form::Sales::Pages::Buyer1IncomeMaxValueCheck, type: :model do
let(:page_id) { "prefix_buyer_1_income_max_value_check" } let(:page_id) { "prefix_buyer_1_income_max_value_check" }
let(:page_definition) { nil } let(:page_definition) { nil }
let(:subsection) { instance_double(Form::Subsection) } let(:form) { instance_double(Form, start_date: Time.zone.local(2024, 4, 1)) }
let(:subsection) { instance_double(Form::Subsection, form:) }
it "has correct subsection" do it "has correct subsection" do
expect(page.subsection).to eq(subsection) expect(page.subsection).to eq(subsection)

3
spec/models/form/sales/pages/buyer1_income_min_value_check_spec.rb

@ -5,7 +5,8 @@ RSpec.describe Form::Sales::Pages::Buyer1IncomeMinValueCheck, type: :model do
let(:page_id) { "prefix_buyer_1_income_min_value_check" } let(:page_id) { "prefix_buyer_1_income_min_value_check" }
let(:page_definition) { nil } let(:page_definition) { nil }
let(:subsection) { instance_double(Form::Subsection) } let(:form) { instance_double(Form, start_date: Time.zone.local(2024, 4, 1)) }
let(:subsection) { instance_double(Form::Subsection, form:) }
it "has correct subsection" do it "has correct subsection" do
expect(page.subsection).to eq(subsection) expect(page.subsection).to eq(subsection)

3
spec/models/form/sales/pages/buyer2_income_max_value_check_spec.rb

@ -5,7 +5,8 @@ RSpec.describe Form::Sales::Pages::Buyer2IncomeMaxValueCheck, type: :model do
let(:page_id) { "prefix_buyer_2_income_max_value_check" } let(:page_id) { "prefix_buyer_2_income_max_value_check" }
let(:page_definition) { nil } let(:page_definition) { nil }
let(:subsection) { instance_double(Form::Subsection) } let(:form) { instance_double(Form, start_date: Time.zone.local(2024, 4, 1)) }
let(:subsection) { instance_double(Form::Subsection, form:) }
it "has correct subsection" do it "has correct subsection" do
expect(page.subsection).to eq(subsection) expect(page.subsection).to eq(subsection)

3
spec/models/form/sales/pages/buyer2_income_min_value_check_spec.rb

@ -5,7 +5,8 @@ RSpec.describe Form::Sales::Pages::Buyer2IncomeMinValueCheck, type: :model do
let(:page_id) { "prefix_buyer_2_income_min_value_check" } let(:page_id) { "prefix_buyer_2_income_min_value_check" }
let(:page_definition) { nil } let(:page_definition) { nil }
let(:subsection) { instance_double(Form::Subsection) } let(:form) { instance_double(Form, start_date: Time.zone.local(2024, 4, 1)) }
let(:subsection) { instance_double(Form::Subsection, form:) }
it "has correct subsection" do it "has correct subsection" do
expect(page.subsection).to eq(subsection) expect(page.subsection).to eq(subsection)

3
spec/models/form/sales/pages/combined_income_max_value_check_spec.rb

@ -5,7 +5,8 @@ RSpec.describe Form::Sales::Pages::CombinedIncomeMaxValueCheck, type: :model do
let(:page_id) { "prefix_combined_income_max_value_check" } let(:page_id) { "prefix_combined_income_max_value_check" }
let(:page_definition) { nil } let(:page_definition) { nil }
let(:subsection) { instance_double(Form::Subsection) } let(:form) { instance_double(Form, start_date: Time.zone.local(2024, 4, 1)) }
let(:subsection) { instance_double(Form::Subsection, form:) }
it "has correct subsection" do it "has correct subsection" do
expect(page.subsection).to eq(subsection) expect(page.subsection).to eq(subsection)

3
spec/models/form/sales/pages/deposit_value_check_spec.rb

@ -5,7 +5,8 @@ RSpec.describe Form::Sales::Pages::DepositValueCheck, type: :model do
let(:page_id) { "deposit_value_check" } let(:page_id) { "deposit_value_check" }
let(:page_definition) { nil } let(:page_definition) { nil }
let(:subsection) { instance_double(Form::Subsection) } let(:form) { instance_double(Form, start_date: Time.zone.local(2024, 4, 1)) }
let(:subsection) { instance_double(Form::Subsection, form:) }
it "has correct subsection" do it "has correct subsection" do
expect(page.subsection).to eq(subsection) expect(page.subsection).to eq(subsection)

3
spec/models/form/sales/pages/mortgage_value_check_spec.rb

@ -6,7 +6,8 @@ RSpec.describe Form::Sales::Pages::MortgageValueCheck, type: :model do
let(:page_id) { "buyer_1_income_mortgage_value_check" } let(:page_id) { "buyer_1_income_mortgage_value_check" }
let(:page_definition) { nil } let(:page_definition) { nil }
let(:index) { 1 } let(:index) { 1 }
let(:subsection) { instance_double(Form::Subsection) } let(:form) { instance_double(Form, start_date: Time.zone.local(2024, 4, 1)) }
let(:subsection) { instance_double(Form::Subsection, form:) }
it "has correct subsection" do it "has correct subsection" do
expect(page.subsection).to eq(subsection) expect(page.subsection).to eq(subsection)

3
spec/models/form/sales/pages/savings_value_check_spec.rb

@ -5,7 +5,8 @@ RSpec.describe Form::Sales::Pages::SavingsValueCheck, type: :model do
let(:page_id) { "savings_value_check" } let(:page_id) { "savings_value_check" }
let(:page_definition) { nil } let(:page_definition) { nil }
let(:subsection) { instance_double(Form::Subsection) } let(:form) { instance_double(Form, start_date: Time.zone.local(2024, 4, 1)) }
let(:subsection) { instance_double(Form::Subsection, form:) }
it "has correct subsection" do it "has correct subsection" do
expect(page.subsection).to eq(subsection) expect(page.subsection).to eq(subsection)

3
spec/models/form/sales/subsections/discounted_ownership_scheme_spec.rb

@ -5,7 +5,8 @@ RSpec.describe Form::Sales::Subsections::DiscountedOwnershipScheme, type: :model
let(:subsection_id) { nil } let(:subsection_id) { nil }
let(:subsection_definition) { nil } let(:subsection_definition) { nil }
let(:section) { instance_double(Form::Sales::Sections::SaleInformation) } let(:form) { instance_double(Form, start_date: Time.zone.local(2024, 4, 1)) }
let(:section) { instance_double(Form::Sales::Sections::SaleInformation, form:) }
it "has correct section" do it "has correct section" do
expect(discounted_ownership_scheme.section).to eq(section) expect(discounted_ownership_scheme.section).to eq(section)

2
spec/models/form/sales/subsections/shared_ownership_scheme_spec.rb

@ -8,7 +8,7 @@ RSpec.describe Form::Sales::Subsections::SharedOwnershipScheme, type: :model do
let(:section) { instance_double(Form::Sales::Sections::SaleInformation) } let(:section) { instance_double(Form::Sales::Sections::SaleInformation) }
before do before do
allow(section).to receive(:form).and_return(instance_double(Form, start_year_after_2024?: false)) allow(section).to receive(:form).and_return(instance_double(Form, start_year_after_2024?: false, start_date: Time.zone.local(2023, 4, 1)))
end end
it "has correct section" do it "has correct section" do

50
spec/models/validations/sales/household_validations_spec.rb

@ -15,11 +15,11 @@ RSpec.describe Validations::Sales::HouseholdValidations do
record.relat3 = "P" record.relat3 = "P"
household_validator.validate_partner_count(record) household_validator.validate_partner_count(record)
expect(record.errors["relat2"]) expect(record.errors["relat2"])
.to include(match I18n.t("validations.household.relat.one_partner")) .to include(match I18n.t("validations.sales.household.relat.one_partner"))
expect(record.errors["relat3"]) expect(record.errors["relat3"])
.to include(match I18n.t("validations.household.relat.one_partner")) .to include(match I18n.t("validations.sales.household.relat.one_partner"))
expect(record.errors["relat4"]) expect(record.errors["relat4"])
.not_to include(match I18n.t("validations.household.relat.one_partner")) .not_to include(match I18n.t("validations.sales.household.relat.one_partner"))
end end
it "expects that a tenant can have a partner" do it "expects that a tenant can have a partner" do
@ -47,9 +47,9 @@ RSpec.describe Validations::Sales::HouseholdValidations do
record.relat2 = "P" record.relat2 = "P"
household_validator.validate_person_age_matches_relationship(record) household_validator.validate_person_age_matches_relationship(record)
expect(record.errors["relat2"]) expect(record.errors["relat2"])
.to include(match I18n.t("validations.household.relat.child_under_16_sales", person_num: 2)) .to include(match I18n.t("validations.sales.household.relat.child_under_16", person_num: 2))
expect(record.errors["age2"]) expect(record.errors["age2"])
.to include(match I18n.t("validations.household.age.child_under_16_relat_sales", person_num: 2)) .to include(match I18n.t("validations.sales.household.age.child_under_16", person_num: 2))
end end
end end
@ -58,9 +58,9 @@ RSpec.describe Validations::Sales::HouseholdValidations do
record.relat2 = "C" record.relat2 = "C"
household_validator.validate_person_age_matches_relationship(record) household_validator.validate_person_age_matches_relationship(record)
expect(record.errors["relat2"]) expect(record.errors["relat2"])
.to include(match I18n.t("validations.household.relat.child_over_20")) .to include(match I18n.t("validations.sales.household.relat.child_over_20"))
expect(record.errors["age2"]) expect(record.errors["age2"])
.to include(match I18n.t("validations.household.age.child_over_20")) .to include(match I18n.t("validations.sales.household.age.child_over_20"))
end end
end end
@ -94,9 +94,9 @@ RSpec.describe Validations::Sales::HouseholdValidations do
record.ecstat2 = 1 record.ecstat2 = 1
household_validator.validate_person_age_matches_economic_status(record) household_validator.validate_person_age_matches_economic_status(record)
expect(record.errors["ecstat2"]) expect(record.errors["ecstat2"])
.to include(match I18n.t("validations.household.ecstat.child_under_16", person_num: 2)) .to include(match I18n.t("validations.sales.household.ecstat.child_under_16", person_num: 2))
expect(record.errors["age2"]) expect(record.errors["age2"])
.to include(match I18n.t("validations.household.age.child_under_16_ecstat", person_num: 2)) .to include(match I18n.t("validations.sales.household.age.child_under_16_ecstat", person_num: 2))
end end
it "expects that person's economic status is Child" do it "expects that person's economic status is Child" do
@ -112,9 +112,9 @@ RSpec.describe Validations::Sales::HouseholdValidations do
record.ecstat2 = 9 record.ecstat2 = 9
household_validator.validate_person_age_matches_economic_status(record) household_validator.validate_person_age_matches_economic_status(record)
expect(record.errors["ecstat2"]) expect(record.errors["ecstat2"])
.to include(match I18n.t("validations.household.ecstat.child_over_16", person_num: 2)) .to include(match I18n.t("validations.sales.household.ecstat.child_over_16", person_num: 2))
expect(record.errors["age2"]) expect(record.errors["age2"])
.to include(match I18n.t("validations.household.age.child_over_16", person_num: 2)) .to include(match I18n.t("validations.sales.household.age.child_over_16", person_num: 2))
end end
end end
@ -126,9 +126,9 @@ RSpec.describe Validations::Sales::HouseholdValidations do
record.ecstat2 = 1 record.ecstat2 = 1
household_validator.validate_person_age_matches_economic_status(record) household_validator.validate_person_age_matches_economic_status(record)
expect(record.errors["ecstat2"]) expect(record.errors["ecstat2"])
.not_to include(match I18n.t("validations.household.ecstat.child_under_16", person_num: 2)) .not_to include(match I18n.t("validations.sales.household.ecstat.child_under_16", person_num: 2))
expect(record.errors["age2"]) expect(record.errors["age2"])
.not_to include(match I18n.t("validations.household.age.child_under_16_ecstat", person_num: 2)) .not_to include(match I18n.t("validations.sales.household.age.child_under_16_ecstat", person_num: 2))
end end
end end
end end
@ -143,11 +143,11 @@ RSpec.describe Validations::Sales::HouseholdValidations do
record.relat2 = "C" record.relat2 = "C"
household_validator.validate_child_12_years_younger(record) household_validator.validate_child_12_years_younger(record)
expect(record.errors["age1"]) expect(record.errors["age1"])
.to include(match I18n.t("validations.household.age.child_12_years_younger", person_num: 2)) .to include(match I18n.t("validations.sales.household.age.child_12_years_younger", person_num: 2))
expect(record.errors["age2"]) expect(record.errors["age2"])
.to include(match I18n.t("validations.household.age.child_12_years_younger", person_num: 2)) .to include(match I18n.t("validations.sales.household.age.child_12_years_younger", person_num: 2))
expect(record.errors["relat2"]) expect(record.errors["relat2"])
.to include(match I18n.t("validations.household.age.child_12_years_younger", person_num: 2)) .to include(match I18n.t("validations.sales.household.age.child_12_years_younger", person_num: 2))
end end
it "expects the child is at least 12 years younger than buyer 1" do it "expects the child is at least 12 years younger than buyer 1" do
@ -206,11 +206,11 @@ RSpec.describe Validations::Sales::HouseholdValidations do
record.relat2 = "C" record.relat2 = "C"
household_validator.validate_person_age_and_relationship_matches_economic_status(record) household_validator.validate_person_age_and_relationship_matches_economic_status(record)
expect(record.errors["relat2"]) expect(record.errors["relat2"])
.to include(match I18n.t("validations.household.relat.student_16_19.cannot_be_child.16_19_not_student")) .to include(match I18n.t("validations.sales.household.relat.student_16_19.cannot_be_child.16_19_not_student"))
expect(record.errors["age2"]) expect(record.errors["age2"])
.to include(match I18n.t("validations.household.age.student_16_19.cannot_be_16_19.child_not_student")) .to include(match I18n.t("validations.sales.household.age.student_16_19.cannot_be_16_19.child_not_student"))
expect(record.errors["ecstat2"]) expect(record.errors["ecstat2"])
.to include(match I18n.t("validations.household.ecstat.student_16_19.must_be_student")) .to include(match I18n.t("validations.sales.household.ecstat.student_16_19.must_be_student"))
end end
it "adds errors for a person who is a child of the buyer and a student but not aged 16-19" do it "adds errors for a person who is a child of the buyer and a student but not aged 16-19" do
@ -219,11 +219,11 @@ RSpec.describe Validations::Sales::HouseholdValidations do
record.relat2 = "C" record.relat2 = "C"
household_validator.validate_person_age_and_relationship_matches_economic_status(record) household_validator.validate_person_age_and_relationship_matches_economic_status(record)
expect(record.errors["relat2"]) expect(record.errors["relat2"])
.to include(match I18n.t("validations.household.relat.student_16_19.cannot_be_child.student_not_16_19")) .to include(match I18n.t("validations.sales.household.relat.student_16_19.cannot_be_child.student_not_16_19"))
expect(record.errors["age2"]) expect(record.errors["age2"])
.to include(match I18n.t("validations.household.age.student_16_19.must_be_16_19")) .to include(match I18n.t("validations.sales.household.age.student_16_19.must_be_16_19"))
expect(record.errors["ecstat2"]) expect(record.errors["ecstat2"])
.to include(match I18n.t("validations.household.ecstat.student_16_19.cannot_be_student.child_not_16_19")) .to include(match I18n.t("validations.sales.household.ecstat.student_16_19.cannot_be_student.child_not_16_19"))
end end
end end
@ -316,9 +316,9 @@ RSpec.describe Validations::Sales::HouseholdValidations do
it "triggers a validation if buyer two will also not live in the property" do it "triggers a validation if buyer two will also not live in the property" do
sales_log.buy2livein = 2 sales_log.buy2livein = 2
household_validator.validate_buyers_living_in_property(sales_log) household_validator.validate_buyers_living_in_property(sales_log)
expect(sales_log.errors[:buylivein]).to include I18n.t("validations.household.buylivein.buyers_will_live_in_property_values_inconsistent_setup") expect(sales_log.errors[:buylivein]).to include I18n.t("validations.sales.household.buylivein.buyers_will_live_in_property_values_inconsistent")
expect(sales_log.errors[:buy2livein]).to include I18n.t("validations.household.buylivein.buyers_will_live_in_property_values_inconsistent") expect(sales_log.errors[:buy2livein]).to include I18n.t("validations.sales.household.buy2livein.buyers_will_live_in_property_values_inconsistent")
expect(sales_log.errors[:buy1livein]).to include I18n.t("validations.household.buylivein.buyers_will_live_in_property_values_inconsistent") expect(sales_log.errors[:buy1livein]).to include I18n.t("validations.sales.household.buy1livein.buyers_will_live_in_property_values_inconsistent")
end end
end end
end end

Loading…
Cancel
Save